简单提要
组件通信主要方式有四种:
1.通过prop进行组件之间的单向通讯(父子组件之间的单向通讯)=>特点:
父组件值改变,子组件相应改变.但子组件改变不影响父组件
<div style="color: red;margin-top: 15px">正常父子组件(单向)通讯: 父组件值改变,子组件相应改变.但子组件改变不影响父组件</div>
<div id="parent">
<span>父组件</span>
<input type="text" v-model="parentMessage">
<br>
<child :message="parentMessage"></child>
</div>
<script>
Vue.component('child', {
props: ['message'],
template: `<div>
<span>子组件</span>
<input type="text" v-model="message">
</div>`,
});
new Vue({
el: '#parent',
data: {
parentMessage: 'hello, child!'
}
});
</script>
2.通过组件的自定义事件进行组件之间的单向通讯(子父组件之间的单向通讯)=>特点
子组件值改变,父组件相应改变.但父组件改变不影响子组件
<div style="color: red;margin-top: 15px">子父组件单向通讯: 子组件通过触发父组件事件改变父组件的值</div>
<div id="parent3">
<span>父组件</span>
<input type="text" v-model="parentMessage">
<br>
<!---注意下面这行用的是.sync修饰符--->
<child3 @update:message="parentMessage2"></child3>
</div>
<script>
Vue.component('child3', {
data(){
return{
message:'hello, parent!'
}
},
template: `<div>
<span>子组件</span>
<input type="text" v-model="message">
</div>`,
watch: {
message:function () {
this.$emit('update:message', this.message);
}
},
mounted(){
this.$emit('update:message', this.message);
}
});
new Vue({
el: '#parent3',
data: {
parentMessage: 'hello!'
},
methods: {
parentMessage2(msg) {
this.parentMessage = msg;
}
}
});
</script>
3.通过组件的自定义事件进行组件之间的(双向)通讯=>特点
(利用prop特性)子组件通过触发父组件事件改变其自身的值从而改变子组件的值
<div style="color: red;margin-top: 15px">正常子父组件(双向)通讯(不使用.sync修饰符): (利用prop特性)子组件通过触发父组件事件改变其自身的值从而改变子组件的值</div>
<div id="parent2">
<span>父组件</span>
<input type="text" v-model="parentMessage">
<br>
<child2 :message="parentMessage" @update:message="parentMessage2"></child2>
</div>
<script>
Vue.component('child2', {
props: ['message'],
template: `<div>
<span>子组件</span>
<input type="text" v-model="message">
</div>`,
watch: {
message: function () {
this.$emit('update:message', this.message);
}
}
});
new Vue({
el: '#parent2',
data: {
parentMessage: 'hello, child!'
},
methods: {
parentMessage2(msg) {
this.parentMessage = msg;
}
}
});
</script>
关于该类方法实现的组件之间的双向通信,官方提供了一种 .sync
修饰符来简化实现
<div style="color: red;margin-top: 15px">正常子父组件(双向)通讯(使用.sync修饰符): (利用prop特性)子组件通过触发父组件事件改变其自身的值从而改变子组件的值</div>
<div>使用使用.sync修饰符的好处是:省略在父组件上给子组件添加监听方法,且也省略了实现该方法的主体。在子组件中直接使用 this.$emit('update:value', this.value) value为子组件中的props的key 来触发父组件值得改变同时响应子组件的值一起改变(说白了就是遵循prop单向数据流规则)</div>
<div id="parent5">
<span>父组件</span>
<input type="text" v-model="parentMessage">
<br>
<!---注意下面这行用的是.sync修饰符--->
<child5 :message.sync="parentMessage"></child5>
</div>
<script>
Vue.component('child5', {
props: ['message'],
template: `<div>
<span>子组件</span>
<input type="text" v-model="message">
</div>`,
watch: {
message: function () {
this.$emit('update:message', this.message);
}
}
});
new Vue({
el: '#parent5',
data: {
parentMessage: 'hello, child!'
},
methods: {
}
});
</script>
使用使用.sync修饰符的好处是:省略在父组件上给子组件添加监听方法,且也省略了实现该方法的主体。在子组件中直接使用 this.$emit('update:value', this.value) value为子组件中的props的key 来触发父组件值得改变同时响应子组件的值一起改变
4.通过vue事件总线进行组件之间的(双向或单向)通讯=>特点
<div style="color: red;margin-top: 15px">vue事件总线</div>
<div id="parent4">
<span>父组件</span>
<input type="text" v-model="parentMessage">
<br>
<child4></child4>
</div>
<script>
var relay = new Vue();
Vue.component('child4', {
data(){
return{
message:'hello, parent!'
}
},
watch:{
message(){
relay.$emit("parent",{message:this.message})
}
},
template: `<div>
<span>子组件</span>
<input type="text" v-model="message">
</div>`,
mounted() {
relay.$on("child",(options)=>{
this.message=options.parentMessage;
});
relay.$emit("parent",{message:this.message})
}
});
new Vue({
el: '#parent4',
data: {
parentMessage: 'hello, child!'
},
watch:{
parentMessage(){
relay.$emit("child",{parentMessage:this.parentMessage})
}
},
mounted() {
relay.$on("parent",(options)=>{
this.parentMessage=options.message;
});
relay.$emit("child",{parentMessage:this.parentMessage})
}
});
</script>
当然这四种是比较常用的 实现组件通信还可以使用:
处理边界情况
- 通过$parent属性访问父组件
- 通过children属性访问子组件
- 给组件命名,通过指定名称来访问
<base-input ref="usernameInput"></base-input >
this.$refs.usernameInput
- 等等 ····
网友评论