目的:1、父子组件之间可以相互修改数据。
自定义组件v-model
一个组件上的v-model默认会利用名为value的prop和名为input的事件,但是像单选框,复选框等类型的输入控件可能会将value特性用于不同的目的。
v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后做了两个操作:
1.v-bind绑定一个value属性
2.v-on指令给当前元素绑定input事件
例如,在原生表单元素中:
相当于:
v-model用于自定义组件中,应该使用以下操作:
1.接收一个value prop。
2.触发input事件,并传入新值。
例如,在自定义组件中:
相当于
注:这个时候,inputValue接受的值就是input事件的回调函数的第一个参数,所以在自定义组件中,要实现数据绑定,还需要$emit去触发input的事件。
this. $emit(‘input’,value)
v-model主要针对表单实现数据双向绑定,如果要对组件实现双向绑定,可以想象把子组件变成表单,所以此时使用input关键字。
v-model是vue2中唯一支持双向绑定的指令,用于表单控件绑定,v-model其实是个语法糖。
如://这不过是一下示例的语法糖://简写
也就是说,你只需要在组件中声明一个name为value的props,并且通过触发input事件传入一个值,就能修改这个value.
例如:
父组件代码:
子组件代码:
实例3,当子组件值改变时,父组件的值同时改变,实现双向绑定,
父组件内容:
子组件内容:
使用.sync及update实现父子双向绑定
例如,父子键中有一个按钮可以改变父组件中的值同时也可以改变子组件的值,子组件中有一个按钮既可以改变子组件中的值也可以改变父组件中的值,实现子父组件双向绑定:
父组件代码:
子组件代码:
.sync修饰符
该修饰符被扩展为一个自动更新父组件属性的v-on监听器。
如下代码:
子组件代码:
默认初始值是{{show}},所以是显示的
关闭总结:
vue修饰符.sync的功能是:当一个子组件改变了一个prop的值时,这个变化也会同步到父组件中所绑定。1.父组件可以调用子组件通过props导出的数据。
2.子组件可以使用$emit触发父组件的自定义事件。
$emit语法:
vm. $emit(eventName,[…args]);
参数说明:第一个参数eventName,表示自定义事件名称。
第二个参数[…args],表示要传给父组件的参数,附加参数都会传给监听器回调。
不带参数$emit用法:
子组件:
父组件:
带参数的$emit:
在子组件中:
在父组件中:
示例2:
在子组件中
在父组件中我们在vue的父子组件传值的时候,我们先在需要的子组件上用props注册一些属性,然后父组件调用的时候当属性来传值。
如果我们给child传props没有注册的属性,我们就要用$attrs来取了。
现有父组件A和子组件B:
组件A的内容如下:
组件B的内容如下:
组件B只导出了w1,在组件A中调用时,多了几个属性w2,w3,在组件B中可以使用console.log(this.$attrs)查看非prop属性,结果为一个对象{w2: “world”, w3: “myname”}
但是在控制台看到B组件的根元素div上出现了这两个属性,显示结果为:
如果想要去除这两个属性,可以在子组件中添加inheritAttrs:false
格式如下:export default {props:["w1"],inheritAttrs:false,data(){return{}}}
inheritAttrs
inheritAttrs:false,如果你不希望组件的根元素继承特性,你可以在组件的选项中设置,这尤其适合配合实例的 $ attrs 属性使用,该属性包含了传递给一个组件的特性名和特性值。
1.inheritAttrs默认为true,即允许继承的意思,如果设为false,即禁止继承。
2.$attrs为组件标签内没有在组件内用props声明的属性(除了style和class)
小结:
$ attrs
$ attrs存储非prop特性,$attrs继承所有的父组件属性,但是除了prop传递的属性,style和class
inheritAttrs
inheritAttrs控制vue对非prop特性的默认行为。默认为true,继承所有的父组件属性(除props的特定绑定)作为普通的HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继续特性设置inheritAttrs:false,但是class属性会继承。
多级组件传递数据
现有A,B,C三个组件依次嵌套,示例:
A到B可以通过props的方式向子组件传递值,如果A组件与C组件之间通过怎么办呢?
A和C之间属于跨多级的组件嵌套关系,要解决这一问题可以使用 $ attrs解决。
在组件C中,代码如下:
在组件B中代码如下:
在组件A代码中:
1.父组件调用子组件
子组件children.vue代码如下:
父组件parent.vue代码如下:
此时在子组件中的内容会显示在组件中,总结:父组件调用子组件
(1)在父组件中通过import导入子组件。
(2)在父组件中使用components:{}注册子组件。
2.父组件向子组件传值
在子组件中,写入一个动态数据message,然后通过props把数据导出去,为外部父组件调用提供一个接口:
子组件代码如下:
在父组件中给message赋值:
在父组件中,在子组件上为:message赋值。
总结,父组件给子组件传值:子组件中要通过props把变量导出来,然后在父组件中使用该变量,为该变量赋值。
注:如果父组件传值为一个静态的值,也需要使用v-bind来告诉vue,v-bind简写为":"例如:简写为:
3.为子组件重命名
在父组件中为子组件重命名,可以在components中为子组件重命名,格式如下:
4.props用法
props通常是以字符串数组的形式列出,例如:props:["name","age","color","job","adress"],
如果希望每个字符串都有指定值类型,可以为它定义属性:props:{name:String,age:Number,color:Boolean,job:Array,adress:Object},
当父组件赋值类型不对时,浏览器控制台会提示错误信息。
5.让一个对象的属性作为prop传入
传入一个对象的所有属性,如果想让一个对象的属性作为prop传入:
子组件代码如下:
父组件中定义一个对象post,它有两个属性,id和title,父组件代码如下:
注释:
等价于
6.传递静态或动态prop
传入一个静态的值:
动态赋值:
任何类型的值都可以传给prop,
7.单向数据流
所有的prop都使得其父子prop之间形成了一个单向下绑定:父级prop的更新会向下流动到子组件中,但是反过来则不行,这样会防止从子组件意外改变父组件的状态。
每次父级组件发生更新时,子组件中所有的prop都将会刷新为最新的值,这意味着你不应该在一个子组件内部改变prop,如果这样会在浏览器控制台报错。
这里有两中常见的试图改变一个prop的情形:
(1)这个prop用来传递一个初始值,这个子组件接下来希望将其作为一个本地的prop数据来使用,在这种情况下,最好定义一个本地的data属性并将这个prop用作其初始值。
在子组件中,有两个变量,childtitle和mycount,把childtitle导出从父组件获取值,然后传给mycount:
count数据:{{mycount}}
父级组件代码中,给childtitle赋值,此时,当点击按钮时,childtitle的值会变化:
以上会出现一个问题,当点击按钮时childtitle的值会跟着变化,但是子组件中mycount的值不会变化,这时mycoun需要使用计算属性computed才能使值跟着变化,子组件中的代码更改如下:
count数据:{{mycount}}
8.prop验证
我们可以为组件的prop指定验证要求,例如你知道的这些类型,如果有一个需求没有被满足,则Vue会在浏览器控制台发出警告。
为了定制prop的验证方式,你可以为props中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:props: {// 指定基础类型检查proA: Number,// 可以设置多个类型,该值符合其中一个即可proB: [String, Number],// 如果该变量必须存在,必填,可以设置required为true,可以通过type设置该值得类型proC: { type: Number, required: true},// 可以使用default设置默认的值proD: { type: Number, default: 100},// 可以设置带有默认值得对象proE: { type: Object, //注:对象或数组默认值必须从一个工厂函数获取 default: function() {return { meseage: "hello"}; }},// 可以自定义验证函数proF: { validator: function(value) {//这个值必须匹配下列字符串中的一个return ["success", "warning", "danger"].indexOf(value) !== -1; }}
},
当父级组件传过来的值不符合条件,验证失败时,vue控制台会发生警告。
注:prop会在一个组件实例创建之前进行验证,所以实例的属性(如data,computed)在default或validator函数中是不可用的。
type类型包括:
String
Number
Boolean
Array
Object
Date
Function
Symbol
注:type还可以是一个自定义的构造函数,并且通过instanceof来进行检查确认。
例如如下构造函数:function Person (firstName, lastName) {
this.firstName = firstName this.lastName = lastName}
可以使用以下方式来验证prop的值是否通过new Person创建的。Vue.component('blog-post', {
props: {author: Person }})