【Vue】组件部分知识+.sync修饰符原理+v-model原理
1.脚手架引用组件
全局应用在main.js中
import children from './components/children.vue'
Vue.component("children",children)
局部引用在对应的vue文件中
<children></children>
import children from "@/components/children.vue";
export default {
components: {
children
},
}
2.组件中data必须是函数
js中对象类型变量保存的实际上是对象的引用,存在多个组件会共享数据,导致一个组件中数据的改变会引起其他组件数据的改变。
而使用一个返回对象的函数,每次使用组件都会创建一个新的对象,这样就不会出现共享数据的问题了。
3.属性Prop
3.1prop的大小写
html中的attribute对大小写不敏感,所有浏览器会把大写解析成小写,使用时驼峰命名的prop名要使用等价的短横线分割命名
// 使用时短横线分隔符 <children :prop-a=""></children> // 组件中驼峰定义 props: ["propA", "propB"]
3.2静态动态prop
静态传递直接传入静态值,动态传递用v-bind
3.3单向数据流
父子prop之间形成单行下行绑定:父级prop更新会向下流动到子组件中,反过来则不行。
每次父组件发生更新,子组件中所有的prop都将会刷新为最新的值。意味这你不应该在一个子组件内部改变prop,否则控制台会警告。
注意:
1.父组件传递的属性是引用类型,在子组件中更改相应的属性会导致父组件相应属性的更改
2.父组件传递的属性是基本类型时,在子组件中更改这个属性会报错。正确的做法是在父组件中绑定属性时时加上.sync修饰符,然后在子组件中改变相应的属性。无论直接改变还是加了修饰符后改变控制台都会报错:

3.如果希望在子组件对传入的prop进行操作,建议在组件中data或computed创建新属性并以传递进来的值进行初始化,而引用类型避免影响父组件中相应数据最后进行深复制。
3.4.sync修饰符的原理
.sync实现双向绑定,即可以把子组件的改变传递到父组件
子组件
<footer @click="change">{{str}}</footer>
change(){
this.$emit('update:str','change')
}
父组件
<children :str="str" @update:str="str=$event"></children>
为了方便提供了一个缩写模式,即.sync修饰符
父组件 <text-document :title.sync="doc.title"></text-document> 子组件
this.$emit('update:title',2)
注意.sync修饰符的v-bind不能和表达式一起使用列如:title.sync=“doc.title+'!”。你只能提供你想要绑定的属性名类似于v-model。
3.5.prop验证
props: {
typePropA: String, //基础类型检查
typePropB: [String, Number, Boolean, Function, Object, Array, Symbol, Date] // 多个可能的类型
// 必传
requiredProp:{
type:String,
required:true,
},
// 默认值
defaultProp:{
type:String,
default:1
},
// 对象或数组默认值必须从一个工厂函数获取
obj: {
type: Object,
default() {
return { message: "hello" };
}
},
// 自定义验证函数
validatorProp: {
type: Number,
validator: function(value) {
return value > 10;
},
default: 12
}
},
prop的type可以是原生构造函数中的一个,也可以自己自定义构造函数使用,并且通过instanceof来进行检查确认
String, Number, Boolean, Function, Object, Array, Symbol, Date
3.6.非prop类型的attribute
也可以像在html标签中添加data-开头的自定义属性一样,给自定义组件添加任意的属性。这样做的话vue会把这个属性放在自定义组建的根元素。自定义组件的模板只能有一个根元素。
父组件向子组件的非prop属性传值则会覆盖,如果是class和style则才用合并。
4.子向父传递事件
//子
this.$emit('myclick',data1,data2)
//父
<my-component @myclick="functionName"></my-component>
此时不应该传进任何参数,否则子组件暴露出的数据就无法获取了
5.父绑定原生事件,用.native修饰v-on
<my-component @click.native="functionName"></my-component>
6.子组件阻止事件冒泡用.stop修饰
7.组件的切换:is
<component :is="currentTabComponent"></component>
8.缓存组件的状态keep-alive
<keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>
9.异步组件
在大型应用我们将应用分割成一些小的代码块,并且只在需要的时候才从服务器加载。为了简化,Vue允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步保存解析你的组件定义。Vue只有在这个组件需要被渲染的时候才会触发该工厂函数,且会被结构缓存起来供未来重渲染。
Vue.component('async-example', function (resolve, reject) {
//setTimeout是为了演示,如何获取组件取决于你自己
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})
可以调用rehect(reason)来表示加载失败。
推荐做法是将异步组件和webpack的code-splitting功能配合使用:
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
也可以在工厂函数中返回Promise,把webpack2和ES2015语法加载一起,可以写成这样
Vue.component(
'async-webpack-example',
// 这个 `import` 函数会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
路由中有相类似的行为

局部注册可以使用:
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
处理加载状态,也可以返回一个如下格式的对象
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
10.组件中使用v-model
<input v-model="searchText">
v-model原理
<input :value="searchText" @input="searchText = $event.target.value" >
用在组件上即如下:
父组件
<children2 :value="value" @input="getInput"></children2>
子组件内的input必须1.将其value特性绑定到props上;2.input触发时将新值抛出
<template>
<div>
<div>
<input :value="value" @input="$emit('input',$event.target.value)" />
</div>
</div>
</template>
<script>
export default {
props: ["value"],
data() {
return {};
}
};
</script>
11.边界情况
this.$root访问根元素
this.$parent子组件用来访问父组件
用ref赋予id引用,this.$refs拿到对指定元素的访问
<base-input ref="usernameInput"></base-input> this.$refs.input.focus()

浙公网安备 33010602011771号