vue 事件总线( vue-bus)非父子组件传值

vue-bus

一个 Vue.js 事件中心插件,同时支持 Vue 1.0 和 2.0

原因

Vue 2.0 重新梳理了事件系统,因为基于组件树结构的事件流方式实在是让人难以理解,并且在组件结构扩展的过程中会变得越来越脆弱。虽然依然保留了父子组件间的事件流,但有诸多限制,比如不支持跨多层父子组件通信,也没有解决兄弟组件间的通信问题。

Vue 推荐使用一个全局事件中心来分发和管理应用内的所有事件,详见文档。这是一个最佳实践,同时适用于 Vue 1.0 和 2.0。你当然可以声明一个全局变量来使用事件中心,但你如果在使用 webpack 之类的模块系统,这显然不合适。每次使用都手动 import 进来也很不方便,所以就有了这个插件:vue-bus

vue-bus 提供了一个全局事件中心,并将其注入每一个组件,你可以像使用内置事件流一样方便的使用全局事件。

安装

$ npm install vue-bus

如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装 vue-bus:

import Vue from 'vue';
import VueBus from 'vue-bus';

Vue.use(VueBus);

如果使用全局的 script 标签,则无须如此(手动安装)。

使用

监听事件和清除监听
// ...
created() {
  this.$bus.on('add-todo', this.addTodo);
  this.$bus.once('once', () => console.log('这个监听器只会触发一次'));
},
beforeDestroy() {
  this.$bus.off('add-todo', this.addTodo);
},
methods: {
  addTodo(newTodo) {
    this.todos.push(newTodo);
  }
}
触发事件
// ...
methods: {
  addTodo() {
    this.$bus.emit('add-todo', { text: this.newTodoText });
    this.$bus.emit('once');
    this.newTodoText = '';
  }
}

注意:$bus.on $bus.once $bus.off $bus.emit 只是 $bus.$on $bus.$once $bus.$off $bus.$emit 的别名。 详见 API


==========================================================

vue 事件总线问题

在main.js中,构建

eventBus = new Vue();

pageA.vue

在methods中发布事件

eventBus.$emit('test', 123);

应该在pageB.vue生命周期creatd/mounted中触发事件, 

eventBus.$on('test', (content) => {

//content即是出过来的值

});

问题二: 跳转路由

pageA.vue在methods中进行路由跳转,这时候就应在该组件被销毁之前触发:

beforeDestroy (){
eventBus.$emit('testClick', this.msg);

},

pageB.vue:应该在pageB.vue生命周期creatd/mounted中触发事件, 

   eventBus.$on('testClick', val => {  
             console.log(val)

        });  

不要忘记清除事件(要不会触发多次);

 beforeDestroy() {
    eventBus.$off('testClick')
  },


=======================================================================
1.组件通讯

父子组件之间传递数据子组件通过props来接受父组件传递的数据,在兄弟组件之间传递数据的话可以使用框架vuex,对于不是庞大的单页面应用就不太适合使用了, vue 官网提供了一种方法叫做 中央事件总线

// 新建一个 Bus.vue文件,new 一个 vue 实例导出
export default new Vue({
    name: 'bus',
    data () {
        return {
            // code
        }
    }
})

// 可以理解为这是一个传话人员
// 新建一个组件 A
<tempalte>
    <button @click="sendMessage"向组件 B 发送数据</button>
</tempalte>
<script>
import Bus from 'Bus.vue'
    export default {
        name: 'componentA',
        data () {
            return {
                msg: 'the message is from componentA'
            }
        },
        methods: {
            sendMessage () {
                // 假设知道组件 B 有个方法叫做 inceptMessage(接收数据的方法)
                // 组件 A对组件 B 说 我要通过 Bus 这个传话员给你传话了,你先告诉我
                // 这么理解,当组件 A 通过 Bus 传话员去触发inceptMessage这个方法的时候,组件 B 是可以感应到组件 A 调用了这个方法的
                Bus.$emit('inceptMessage', this.msg)
                // Bus 通过触发组件 B 的inceptMessage方法将 msg 发送过去了,这个时候组件 B 还不知道组件 A 给它发送了一条数据
            }
        }
    }
</script>
// 新建一个组件 B
<tempalte>
    // 显示组件 A 传过来的数据
    <h1>{{ fromComponentAMsg }}</h1>
</tempalte>
<script>
import Bus from 'Bus.vue'
    export default {
        name: 'componentB',
        data () {
            return {
                fromComponentAMsg: ''
            }
        },
        methods: {

        },
        mounted () {
            // 这个时候组件 B 知道组件 A 给它传了一条数据过来了,于是赶紧叫 Bus 这个传话员把数据告诉它
            // bus 就告诉组件 B, 组件 A 那边通过inceptMessage传过来一条数据叫 msg
            Bus.$on('inceptMessage',(msg) => {
                this.fromComponentAMsg = msg
            })
        }
    }
</script>


2 . 组件前进刷新,后退不刷新

vue 官网给出的一个方法是通过keep-aliverouter-view包住就能实现组件不刷新显示原来的数据,但是在组件中一般都是前进更新数据返回的时候不刷新保留原来的数据,增加用户体验,通过搜索发现了一个方法

export default {
    name: 'xxx',
    data () {
        //...
    },
    deactivated () {
     this.$destroy()
   },
   methods: {
    // ...
    }
}

$destroy完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。 

这样就可以重新更新数据了                                                                                                                                                  

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue 2 中,父子组件之间的通信可以通过事件总线Vuex 和 provide/inject 来实现。 1. 事件总线 (Event Bus): 在 Vue 实例上创建一个中央事件总线,其他组件可以订阅和触发事件。这种方式适用于简单的组件通信场景。 - 创建事件总线: ```javascript // main.js Vue.prototype.$bus = new Vue(); ``` - 在发送组件中触发事件: ```javascript this.$bus.$emit('event-name', data); ``` - 在接收组件中订阅事件: ```javascript mounted() { this.$bus.$on('event-name', (data) => { // 处理接收到的数据 }); }, ``` 2. Vuex: Vuex 是 Vue.js 官方提供的状态管理库,用于在组件之间共享状态。父子组件通过 Vuex 存储和获取数据。 - 定义和导出 store: ```javascript // store.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { data: null, }, mutations: { setData(state, payload) { state.data = payload; }, }, actions: { updateData({ commit }, payload) { commit('setData', payload); }, }, }); ``` - 在发送组件中使用 dispatch 触发 action: ```javascript this.$store.dispatch('updateData', data); ``` - 在接收组件中使用 mapState 辅助函数获取数据: ```javascript computed: { ...mapState(['data']), }, ``` 3. provide/inject: 使用 provide 和 inject 实现父子组件之间的数据传递。这种方式适用于跨层级的组件通信。 - 在父组件中使用 provide 提供数据: ```javascript provide() { return { data: this.data, }; }, ``` - 在子组件中使用 inject 注入数据: ```javascript inject: ['data'], ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值