父子组件通信
1、父子组件通过prop传递数据
父组件可以将一条数据传递给子组件,这条数据可以是动态的,父组件的数据更改的时候,子组件接收的也会变化。
子组件被动的接收父组件的数据,子组件不要再更改这条数据了。
组件实例的作用域是孤立的,父组件不能直接使用子组件的数据,子组件也不能直接使用父组件的数据。
父组件在调用子组件的时候给子组件传递数据:
我是父组件,这是我的fMsg:{{fMsg}}
父组件给子组件传递数据的时候,子组件需要利用props的属性来确定自己的预期数据,如果儿子没有通过props属性接受传递过来的数据,则数据会以自定义属性的方式,放在儿子最外层的根元素上面。
子组件通过props来接受父组件传递过来的数据,并且通过{{msg}}使用
components:{
son:{
template:"我是son子组件!这是父组件传递给我的msg:{{msg}}",
//接收父组件传递来的属性 msg
props:["msg"]
}
}
2、父组件通过v-bind指令传递自身变量给子组件
我们可以用 v-bind 来动态地将 prop 绑定到父组件的数据。每当父组件的数据变化时,该变化也会传导给子组件。
我是父组件,这是我的fMsg:{{fMsg}}
如果如果父组件传递属性给子组件的时候键名有'-'
子组件接收、使用的时候写成小驼峰的模式
components:{
son:{
template:"我是son子组件!这是父组件传递给我的msg:{{fMsg}}",
//接收父组件传递来的属性 msg
props:["fMsg"]
}
}
3、prop验证传递过来的数据
我们可以为组件的 prop 指定验证规则。如果传入的数据不符合要求,Vue 会发出警告。这对于开发给他人使用的组件非常有用
验证主要分为:类型验证、必传验证、默认值设置、自定义验证
类型验证
// 类型验证
// num:Number //父组件传递过来的num必须是Number类型
// 添加多个类型
num: [Number,String],
规定传递过来的数值类型必须是number,否则系统会报错
必传验证
规定父组件必须给子组件传递该值
//必传验证
// num:{
// required: true
// }
默认值设置
当父组件不给子组件传递该值的时候,给子组件设定一个默认值
// 默认值设置
// num:{
// default:100
// }
自定义验证
//自定义验证
num:{
validator(val){
return val > 100
}
}
规定传递过来的数值必须要大于100,否则系统会报错
4、父子组件依靠应用类型的地址传递共享数据
单向数据流
Prop 是单向绑定的:当父组件的属性变化时,将传递给子组件,但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
这是子组件
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。
所以如果我们想实现父子间的数据共享,依靠的就是应用类型的地址传递,应将message写成对象的形式,传递的时候将对象传递给子组件,子组件引用的时候使用对象的value值。
这是子组件
这时候更改父组件的value值,子组件的数据同步更改,子组件修改value值的时候也同步修改了父组件的数据。这是因为不管是子组件还是父组件,我们操作的都是同一个对象,父组件直接把引用类型的地址传递给子组件,子组件没有直接修改对象,只是更改了里面的属性值。
父组件如果将一个引用类型的动态数据传递给子组件的时候,数据会变成双向控制的,子组件改数据的时候父组件也能接收到数据变化,因为子组件改的时候不是在改数据(地址),而是在改数据里的内容,也就是说引用类型数据的地址始终没有变化,不算改父组件数据。
注意:在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。 message:{val:""}
5、viewmodel关系链
在组件间可以用过ref形成ref链,组件还拥有一个关系链($parent),通过这两种链;理论来说,任意的两个组件都可以互相访问,互相进行通信。
$parent:父组件
$children:子组件
$root:根组件
当子组件在set方法中修改父组件传递过来的值时,系统会报错,因为子组件不能修改父组件的数据。
Vue.component("bbb",{
template:"#bbb",
props:["msg"],
computed:{
/* ownMessage(){
return this.msg;
} */
ownMessage:{
get(){
return this.msg;
},
set(val){
this.msg = val //系统报错:子组件不能更改父组件传递的数据
}
}
}
})
所以这时候要使用$parent,让父组件自己更改自己的数据
set(val){
// this.msg = val //系统报错:子组件不能更改父组件传递的数据
// console.log(this)
// 相当于父组件自己更改了msg数据
this.$parent.msg = val;
}
6、父组件通过ref标记获取子组件的数据
父组件在调用子组件的时候使用ref做标记
父组件的this属性上有$refs标记,通过refs标记拿到子组件
// 通过ref标记更改子组件的数据
// this.$refs.b.message = "哈哈"
组件间不仅可以用过$parent/children/root来获取对应关系的组件,父组件还可以主动的通过ref为子组件做标记 也可以给dom做标记,也会形成ref链,也可以交互.