关于vue的最佳实践(二)— 组件之间的通信机制
vue150 阅读0 评论
父子组件通信机制
父子组件通信机制主要分为两种,
- 父组件传递数据给子组件
- 子组件传递数据给父组件
对于父组件传递数据给子组件,常见方法是props
//父组件
<child :text="text"></child>
//子组件
export default {
props: {
text: {
type: String,
default: ''
}
}
}
而对于子组件传递数据给父组件,方式有:
- 回调传参:既父组件将回调方法作为参数传递给子组件,子组件再进行回调
//父组件
<child :handleChange="handleChange"></child>
export default {
methods: {
handleChange(value) {
///...
}
},
}
//子组件
<button @click="handleChange('value')">click</button>
export default {
props: {
handleChange: {
type: Function,
default: _ => {}
}
}
}
- 自定义事件:子组件通过事件通知父组件
//父组件
<child @childChange="handleChange"></child>
export default {
methods: {
handleChange(value) {
///...
}
},
}
//子组件
<button @click="$emit('childChange', 'value')">click</button>
- 定义ref:父组件通过给子组件定义ref属性,直接通过
vm.$refs.[子组件的ref].[子组件的属性]获取子组件的数据
//父组件
<child ref="child"></child>
export default {
methods: {
getChildData() {
return this.$refs.child.text;
}
}
}
//子组件
export default {
data () {
return {
text: 'text'
}
}
}
除了以上两种之外,我们可能需要对父子组件进行双向绑定,这里我们使用 .sync 修饰符
//父组件
<child :word.sync="text"></child>
export default {
data() {
return{
text: ''
}
}
}
//子组件
<input type="text" v-model="text">
export default {
data() {
return {
text: '',
}
},
props: {
word: {
type: String,
default: ''
}
}
watch: {
text: function(newValue, oldValue) {
//每当text的值改变则发送事件update:word , 并且把值传过去
this.$emit('update:word', newValue)
}
}
}
其实 .sync 修饰符是作为一个编译时的语法糖,会被自动扩展成一个 v-on 监听器:
<child :word.sync="text"></child>
=>
<child :word="text" @update:word="val => text = val"></child>
这种方法跟使用自定义事件监听其实是一个道理,只是更加简便,且两者数据是等价的,而非作为参数进行处理。
非父子组件通信机制
非父子组件通信机制主要分为两种,
- 存在共同祖先的通信机制
- 通过Vuex进行状态管理
对于存在共同祖先的组件,可以通过共同祖先作为媒介进行传递数据,当然如果层次差异太大或者无法使用中间媒介进行传递数据,则可以使用Vuex进行状态管理。
- 发布/订阅模式
使用Vue的 $emit 和 $on 的方法进行通信,如
window.vueBus = new Vue();
// 触发组件 A 中的事件
vueBus.$emit('child:change', 1);
// 在组件 B 创建的钩子中监听事件
vueBus.$on('child:change', id => {
//...
})
或者引用外部的媒介,如PubSub:
//组件A 订阅事件
PubSub.subscribe("close", (event, data) => {
this.close();
});
//组件B 发布事件
PubSub.publish("close", "");
的确,使用发布/订阅模式进行组件间的通信是极其方便的,但是有一点需要注意的是,无论是全局事件或者是分布式事件,这两者都是挂载在全局对象,在页面销毁时,需要将其注册的事件也一同销毁,否者可能将造成内存泄露等问题。
相关文章
评论 (0)
- 还没有评论,来第一条吧。