vue组件通信的几种方式
vue组件通信
父传子
// 父组件 Parent
// 子组件 Child1
{
{ title }}
这种方式是最基础、最简单的方式,详情参考官网即可(vuejs-prop)
子传父
// 子组件 Child
点击我传递数据到父组件
// 父组件
Vue推荐单项数据流,所以子组件想修改父元素传递的数据,需要通知父组件来修改,使用$emit触发父元素传递事件
兄弟组件通信
// 兄弟组件不能直接通信,只需要通过共同的父元素搭桥即可
祖先后代 provide & inject
// 父元素(这里的父元素可以是祖先元素,不一定是直接父级)
// 子孙组件
{
{name}}
这里方式适合层级较多的,比如父子间通过props传递元素给子组件,比较简单,如果在App中需要传递一个数据给它的子子孙孙,那props就太麻烦了,这个时候provide & inject 就可以登场了(这个api在官网不推荐的原因是因为,它适合设计组件库,比如在element-ui的源码中就有使用的); 注意(provide & inject不是响应式的, 如果子元素想通知祖先,就需要hack一下, 按照官网所说,如果传递一个对象,那对象中的的数据还是可以响应的), 还有一点需要注意,在组件中要获取provide 要通过 this._provided才能拿到
- dispatch 子元素向祖先传递数据
main.js
// 使用该方法,需要使用辅助方法,并将辅助方法挂在到Vue原型上
// dispatch的用法,(下面这个方法可以实现,也可以参照element-ui的写法)
Vue.prototype.$dispatch = function (eventName, data) {
// 递归查找父级, 向上传递
let parent = this.$parent
while (parent) { // 查找父元素是否存在
parent.$emit(eventName, data) // 如果存在,则父元素用emit触发事件,并传参,这里的parent就是一个Vue实例
parent = parent.$parent // 递归调用,如果父级存在,那就要把父级赋值给parent,
}
}
传递参数的子组件
<template>
<div class="btn" @click="clickNoticeApp">
我是child1子组件,点击我的时候,传递一个参数到App.vue中,是我的祖先元素
</div>
</template>
<script>
export default {
methods: {
clickNoticeApp () {
this.$dispatch('dispatchName', '你好App,我是child1中传递过来的数据')
}
}
}
</script>
接收参数的祖先元素
export default {
name: 'App',
data () {
return {
msg: ''
}
},
mounted () {
this.$on('dispatchName', mes => {
this.msg = mes // mes就是子组件传递过来的数据了
})
}
}
- boardcast 祖先元素想子元素传递数据
main.js
// boardcast的用法 (下面这个方法可以实现,也可以参照element-ui的写法)
Vue.prototype.$boardcast = function (eventName, data) {
// 递归调用查找子元素, 向下传递
boardcast.call(this, eventName, data)
}
function boardcast (eventName, data) {
this.$children.forEach(child => {
// child 触发事件并携带参数
child.$emit(eventName, data)
if (child) { // 如果子元素存在,则递归调用
boardcast.call(child, eventName, data)
}
})
}
传递参数的祖先元素
<template>
<div class="btn" @click="clickNoticeChild">我是App中的按钮,点击我传递消息给子孙组件</div>
</template>
<script>
export default {
name: 'App',
methods: {
clickNoticeChild () {
this.$boardcast('boardcastName', '我是App中的按钮,点击我可以想子元素传递消息')
}
}
}
</script>
接受参数的子孙元素
<template>
<div style="text-align:center; color:green;">{
{ message }}</div>
</template>
<script>
export default {
data () {
return {
message: ''
}
},
mounted () {
this.$on('boardcastName', data => {
this.message = data
})
}
}
- event-bus 通过event-bus给子元素或者祖先元素传递数据
main.js
// class Bus {
// constructor () {
// this.callbacks = {}
// }
// $on (name, fn) {
// this.callbacks[name] = this.callbacks[name] || []
// this.callbacks[name].push(fn)
// }
// $emit (name, args) {
// if (this.callbacks[name]) {
// 存在 遍历所有callback
// this.callbacks[name].forEach(cb => cb(args))
// }
// }
// }
// Vue.prototype.$bus = new Bus()
// 上述是代码是阐述event-bus实现的机制,主要就是通过$on 和 $emit实现,
// 但是在vue中本身就有这两个方法,所以直接实例化vue就可以了
Vue.prototype.$bus = new Vue()
传递数据的组件
<template>
<div id="app">
<router-view />
<div @click="clickEventBus">我是App中的按钮,点击我通过eventBus传递事件</div>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
clickEventBus () {
this.$bus.$emit('eventBus', '通过Event-bus传递数据')
}
},
}
</script>
接受数据的组件
<template>
<div>
我是子组件中,app通过Event-bus传递数据: {
{msg}}
</div>
</template>
<script>
export default {
data () {
return {
msg: ''
}
},
mounted () {
this.$bus.$on('eventBus', mes => { // msg就是传递的数据
this.msg = mes
})
}
}
</script>
- vuex(这种方式传递数据在项目中运用的也比较多,具体用法参照官网即可,这里就不举例了哈)
最近想把vue的一些知识梳理一下, 希望对大家有所帮助, 还有其他的通讯方式的童鞋,欢迎留言…
还没有评论,来说两句吧...