Arif
  • 124

vue 中 eventbus 的问题

vue 项目有两个组件:hello 组件、apple 组件,这两个组件是兄弟组件,想实现的效果是 hello 组件里的数 num 随机增加之后,apple 组件的 num 也共享这个状态,同时增加。

所以,在全局写了一个 eventbus,然后在 hello 组件里点击增加按钮的时候会发送一个 ‘add’ 事件,把这个 num 发送出去,然后在 apple 组件监听这个 ‘add’ 事件。

写完之后,在 hello 组件里面引入 apple 组件,然后注册,然后写在 template 里,打开浏览器,访问 hello 组件,点击增加按钮,apple 组件会同时更新状态,没有问题。

现在问题来了,我先在 hello 组件点击增加按钮,发送 ‘add’ 之后,然后跳转到 apple 组件页面,发现 num 没有变,这是为什么?这应该不是跨域问题把?

hello 组件代码:

<template>
  <div>
    <h1>hello组件</h1> {{ num }}
    <button @click="handleAdd">随机增加</button>
    <router-link to="/apple">to apple</router-link>
    <Apple></Apple>
  </div>
</template>
<script>
import Apple from './Apple'
export default {
  components: { Apple },
  data () {
    return { num: 0 }
  },
  methods: {
    handleAdd () {
      this.num = Math.floor(Math.random() * 100 + 1)
      this.$bus.emit('add', this.num)
    }
  }
}
</script>

apple 组件代码:

<template>
  <div>
    <h1>apple组件</h1> {{ num }}
  </div>
</template>

<script>
export default {
  data () {
    return { num: 0 }
  },
  created () {
    this.$bus.on('add', val => {this.num = val})
  }
}
</script>

bus 代码:

const install = function (Vue) {
  const Bus = new Vue({
    methods: {
      emit (event, ...args) {
        this.$emit(event, ...args)
      },
      on (event, callback) {
        this.$on(event, callback)
      },
      off (event, callback) {
        this.$off(event, callback)
      }
    }
  })
  Vue.prototype.$bus = Bus
}

export default install

阅读 2.9k
评论 2018-01-06 提问
    3 个回答

    我记得可以这样。你实验一下。
    用一个bus(vue实例)做收发中心,而不只是用来绑定事件。
    类似于这样

    const Bus = new Vue({
        data () {
            return {
                key1:'',
                key2: ''
            }
        },
        created () {
            this.$on('event1', val => {
                this.key1 = val
            }),
            this.$on('event2', val => {
                this.key2 = val
            })
        }
      })
      Vue.prototype.$bus = Bus
    }

    各个组件触发还用

    import bus from 'bus',
    bus.$emit(xxxx)

    获取的时候不用$on,使用计算属性来获取bus的值

    import bus from 'bus'
    computed: {
        key () {
            return bus.key1
        }
    }

    写了个demo,确实可以,为了保证bus一直都在,可以把它添加到到Vue上
    https://jsfiddle.net/8hyL912o/

    评论 赞赏 2018-01-06
      厦冰
      • 8.5k

      1.看到你说的是页面跳转了,在跳转之前发送事件,这个时候apple组件还不在内存里,所以接收不到数据,跳转之后hello组件的生命周期结束,也不在生命周期里了
      2.eventbus只能在都挂载在内存里的组件之间传递数据,像你这种需求可以用vuex,或者在路由之间传递数据

      评论 赞赏 2018-01-06
        NaMoc
        • 87

        请问如果是这样 那怎么解决

        评论 赞赏 2018-08-30
          撰写回答

          登录后参与交流、获取后续更新提醒