一.父给子数据通信
a.使用props
父组件:父组件用绑定语法将自己的变量绑定给子组件定义的公开属性
<ul class="todo-list">
<todo-item v-for="(item, i) of tasks" :key="i" :i="i" @del="del">
<!-- 将i通过绑定语法给子组件添加了i变量-->
<template v-slot:task>{{ item }}</template>
</todo-item>
</ul>
子组件:子组件用props定义公开的属性用于接收父组件的变量值
export default {
props:["i"],
//子组件使用props接收i变量
methods:{
del(){
this.$emit("del",this.i)
}
}
}
b.使用插槽访问(适用于简单的数据展示,数据不需要进行复杂的操作)
父组件:插槽中的的内容取决于父组件如何使用,比如可以使用插值语法将父组件中的变量传递给子组件
<template v-slot:task>{{ item }}</template>
<!-- 使用插槽定义显示内容-->
子组件:子组件定义插槽,使用v-slot的参数形式提供其名称
<slot name="task"></slot>
<!-- 子组件定义插槽-->
二.子给父数据通信
分为两步
1.父组件:在引用的子组件上添加一个自定义事件,监听自定义事件的发生,绑定父组件中的一个处理函数
<todo-item v-for="(item, i) of tasks" :key="i" :i="i" @del="del">
<!-- 父组件添加del自定义事件-->
<template v-slot:task>{{ item }}</template>
</todo-item>
methods:{
del(i) {//父组件的处理函数中执行i的操作
console.log("执行删除操作");
this.tasks.splice(i, 1);
},
}
2.子组件通过$emit(“父亲的自定义事件名称”,参数值)触发事件父组件的自定义事件,传递数据给监听器
<button @click="del">x</button></li>
<!--子组件中触发事件-->
export default {
methods:{
del(){
this.$emit("del",this.i)
//子组件中使用$emit()传参给父组件的del函数
}
}
}
三.兄弟间数据通信
分三步:
1.兄弟间通信需要一个桥梁,定义一个空的vue实例bus保存事件,关联到数据接收方的处理函数上,导入到原来vue的原型对象中,使得bus可以被每个vue的实例使用
2.数据发送方:数据发送方的事件处理函数中,使用this.bus.$emit()触发公共的bus对象保存的事件,并传参
input type="text" v-model="task"><button @click="add">+</button>
//数据发送方,使用$emit()向bus对象上保存的事件传参
methods:{
add(){
this.bus.$emit("add_task",this.task)
this.task="";
}
}
3.数据接收方:在数据加载完成后,向公共的bus对象添加一个自定义的事件,关联到自己的一个处理函数
//数据的接收方,在回调函数中执行操作
created() {
this.bus.$on("add_task",(task)=>{
this.tasks.push(task)
});
//上面一句话等同
//this.bus.$on("add_task", this.add.bind(this));
},
methods: {
add(task) {
this.tasks.push(task);
}
},
四.parent打通父子间相互通信
1.ref被用来给元素或者子组件注册引用信息,引用信息将会注册到父组件的$ref对象上,
2.如果是普通的DOM元素,那么就指向这个DOM元素,
<input type="text" v-model="task" ref="input" /><button @click="add">+</button>
<!--input是普通的dom元素-->
mounted() {
this.$refs.input.focus();
//所以此时指向的是当前页面的标记的input元素
},
使用方法如下:
父组件:
<todo-add ref="todoAdd"></todo-add>
父组件访问子组件:this.$ref.子组件别名.子数据/方法名
methods:{
add(){
this.tasks.push(this.$refs.todoAdd.task)
//访问子组件的task数据
},
del(i){
console.log("删除元素")
this.tasks.splice(i,1)
}
子组件访问父组件:this.$parent.子数据/方法名
methods:{
del(){
//子组件的子组件,使用$parent.$parent访问向上两层的父组件的方法
this.$parent.$parent.del(this.i);
}
}