vue组件通信的几种方式

刺骨的言语ヽ痛彻心扉 2021-12-19 23:19 354阅读 0赞

vue组件通信

  1. 父传子

    // 父组件 Parent




    // 子组件 Child1

这种方式是最基础、最简单的方式,详情参考官网即可(vuejs-prop)

  1. 子传父

    // 子组件 Child

    // 父组件

Vue推荐单项数据流,所以子组件想修改父元素传递的数据,需要通知父组件来修改,使用$emit触发父元素传递事件

  1. 兄弟组件通信

    // 兄弟组件不能直接通信,只需要通过共同的父元素搭桥即可

  2. 祖先后代 provide & inject

    // 父元素(这里的父元素可以是祖先元素,不一定是直接父级)

    // 子孙组件

这里方式适合层级较多的,比如父子间通过props传递元素给子组件,比较简单,如果在App中需要传递一个数据给它的子子孙孙,那props就太麻烦了,这个时候provide & inject 就可以登场了(这个api在官网不推荐的原因是因为,它适合设计组件库,比如在element-ui的源码中就有使用的); 注意(provide & inject不是响应式的, 如果子元素想通知祖先,就需要hack一下, 按照官网所说,如果传递一个对象,那对象中的的数据还是可以响应的), 还有一点需要注意,在组件中要获取provide 要通过 this._provided才能拿到

  1. dispatch 子元素向祖先传递数据
main.js
  1. // 使用该方法,需要使用辅助方法,并将辅助方法挂在到Vue原型上
  2. // dispatch的用法,(下面这个方法可以实现,也可以参照element-ui的写法)
  3. Vue.prototype.$dispatch = function (eventName, data) {
  4. // 递归查找父级, 向上传递
  5. let parent = this.$parent
  6. while (parent) { // 查找父元素是否存在
  7. parent.$emit(eventName, data) // 如果存在,则父元素用emit触发事件,并传参,这里的parent就是一个Vue实例
  8. parent = parent.$parent // 递归调用,如果父级存在,那就要把父级赋值给parent,
  9. }
  10. }
传递参数的子组件
  1. <template>
  2. <div class="btn" @click="clickNoticeApp">
  3. 我是child1子组件,点击我的时候,传递一个参数到App.vue中,是我的祖先元素
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. methods: {
  9. clickNoticeApp () {
  10. this.$dispatch('dispatchName', '你好App,我是child1中传递过来的数据')
  11. }
  12. }
  13. }
  14. </script>
接收参数的祖先元素
  1. export default {
  2. name: 'App',
  3. data () {
  4. return {
  5. msg: ''
  6. }
  7. },
  8. mounted () {
  9. this.$on('dispatchName', mes => {
  10. this.msg = mes // mes就是子组件传递过来的数据了
  11. })
  12. }
  13. }
  1. boardcast 祖先元素想子元素传递数据
main.js
  1. // boardcast的用法 (下面这个方法可以实现,也可以参照element-ui的写法)
  2. Vue.prototype.$boardcast = function (eventName, data) {
  3. // 递归调用查找子元素, 向下传递
  4. boardcast.call(this, eventName, data)
  5. }
  6. function boardcast (eventName, data) {
  7. this.$children.forEach(child => {
  8. // child 触发事件并携带参数
  9. child.$emit(eventName, data)
  10. if (child) { // 如果子元素存在,则递归调用
  11. boardcast.call(child, eventName, data)
  12. }
  13. })
  14. }
传递参数的祖先元素
  1. <template>
  2. <div class="btn" @click="clickNoticeChild">我是App中的按钮,点击我传递消息给子孙组件</div>
  3. </template>
  4. <script>
  5. export default {
  6. name: 'App',
  7. methods: {
  8. clickNoticeChild () {
  9. this.$boardcast('boardcastName', '我是App中的按钮,点击我可以想子元素传递消息')
  10. }
  11. }
  12. }
  13. </script>
接受参数的子孙元素
  1. <template>
  2. <div style="text-align:center; color:green;">{
  3. { message }}</div>
  4. </template>
  5. <script>
  6. export default {
  7. data () {
  8. return {
  9. message: ''
  10. }
  11. },
  12. mounted () {
  13. this.$on('boardcastName', data => {
  14. this.message = data
  15. })
  16. }
  17. }
  1. event-bus 通过event-bus给子元素或者祖先元素传递数据
main.js
  1. // class Bus {
  2. // constructor () {
  3. // this.callbacks = {}
  4. // }
  5. // $on (name, fn) {
  6. // this.callbacks[name] = this.callbacks[name] || []
  7. // this.callbacks[name].push(fn)
  8. // }
  9. // $emit (name, args) {
  10. // if (this.callbacks[name]) {
  11. // 存在 遍历所有callback
  12. // this.callbacks[name].forEach(cb => cb(args))
  13. // }
  14. // }
  15. // }
  16. // Vue.prototype.$bus = new Bus()
  17. // 上述是代码是阐述event-bus实现的机制,主要就是通过$on 和 $emit实现,
  18. // 但是在vue中本身就有这两个方法,所以直接实例化vue就可以了
  19. Vue.prototype.$bus = new Vue()
传递数据的组件
  1. <template>
  2. <div id="app">
  3. <router-view />
  4. <div @click="clickEventBus">我是App中的按钮,点击我通过eventBus传递事件</div>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: 'App',
  10. methods: {
  11. clickEventBus () {
  12. this.$bus.$emit('eventBus', '通过Event-bus传递数据')
  13. }
  14. },
  15. }
  16. </script>
接受数据的组件
  1. <template>
  2. <div>
  3. 我是子组件中,app通过Event-bus传递数据: {
  4. {msg}}
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data () {
  10. return {
  11. msg: ''
  12. }
  13. },
  14. mounted () {
  15. this.$bus.$on('eventBus', mes => { // msg就是传递的数据
  16. this.msg = mes
  17. })
  18. }
  19. }
  20. </script>
  1. vuex(这种方式传递数据在项目中运用的也比较多,具体用法参照官网即可,这里就不举例了哈)

最近想把vue的一些知识梳理一下, 希望对大家有所帮助, 还有其他的通讯方式的童鞋,欢迎留言…

发表评论

表情:
评论列表 (有 0 条评论,354人围观)

还没有评论,来说两句吧...

相关阅读