这是最常用的组件通信方式,适用于父子组件间数据传递
$attrs
和$listeners
来实现父子组件间数据通信嵌套的多层父子组件(只有父子组件两个建议使用props
和$emit
局部组件的使用
在有template选项时,#app里的内容不展示
从这里可以看到KaTeX parse error: Expected '}', got 'EOF' at end of input: … this.emit(‘getCData’, ‘111’)
}` 会触发getCData事件,在B和A组件中都监听了该事件,从而每点击一次C组件文本,都会在控制太打印出相应的内容。如下图所示
当组件不是父子组件关系,比如平行组件间数据通信,或者有两个平行组件A和B,A组件的子组件是C。A和C组件间的数据通信可以使用中央事件总线。
非父子组件数据通信
bus.$emit
(‘自定义事件名’,要传递的值)使用bus.$emit
传递自定义事件和值bus.$on(‘自定义事件名’, eventHandler)
使用bus.$on
在组件的mounted阶段监听自定义事件并在回调函数eventHandler
中作相应的业务处理Vue.component('A', {
template: `
`,
data() {
return {
valueA: '我是A组件的值'
}
},
methods: {
my_click() {
bus.$emit('getAData', this.valueA)
}
},
mounted() {
bus.$on('getCValue', val => this.valueA = val)
}
})
Vue.component('B', {
template: `
`,
data() {
return {
}
}
})
Vue.component('C', {
template: `
`,
data() {
return {
valueC: ''
}
},
methods: {
changeValue(value) {
bus.$emit('getCValue', value)
}
},
mounted() {
bus.$on('getAData', val => {
this.valueC = val
})
}
})
let bus = new Vue()
let vm = new Vue({
el: '#app',
template: `
`
})
上述代码中定义了三个全局组件A,B,C。其中A和B是平行组件,C是B的子组件。
页面效果如下图
A组件中data函数定义了valueA:‘我是A组件的值’,现在想把valueA展示在C组件文本框中。通过点击事件
my_click() { bus.$emit('getAData', this.valueA) }
使用bus.$emit
传递出事件getAData
和valueA
的值。
在C组件的mounted
阶段使用bus.$on('getAData', val => { this.valueC = val })
将传递来的valueA
赋值给valueC
从而将值在C组件中展示。
当C组件的值发生改变时A组件同样能监听到事件从而使文本框的值发生改变。
使用中央事件总线进行数据通信时,需要在同一个Vue实例中使用
$on
监听事件和$emit
来触发事件。上述代码中的事件监听和传递都是在VM实例中的。
在vue中组件间通信还有更多其他方式比如使用
$parent
,$children
,或者使用父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。(这两种很少使用,故不多作赘述)
以及针对大型项目中vuex都能实现组件间通信。
上面讲述的三种组件间通信方式基本满足日常开发需求,根据具体场景选择合适的方式即可。