vue 事件总线( vue-bus)非父子组件传值
vue-bus
一个 Vue.js 事件中心插件,同时支持 Vue 1.0 和 2.0
原因
Vue 2.0 重新梳理了事件系统,因为基于组件树结构的事件流方式实在是让人难以理解,并且在组件结构扩展的过程中会变得越来越脆弱。虽然依然保留了父子组件间的事件流,但有诸多限制,比如不支持跨多层父子组件通信,也没有解决兄弟组件间的通信问题。Vue 推荐使用一个全局事件中心来分发和管理应用内的所有事件,详见文档。这是一个最佳实践,同时适用于 Vue 1.0 和 2.0。你当然可以声明一个全局变量来使用事件中心,但你如果在使用 webpack 之类的模块系统,这显然不合适。每次使用都手动 import 进来也很不方便,所以就有了这个插件:vue-busvue-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-alive将router-view包住就能实现组件不刷新显示原来的数据,但是在组件中一般都是前进更新数据返回的时候不刷新保留原来的数据,增加用户体验,通过搜索发现了一个方法
export default { name: 'xxx', data () { //... }, deactivated () { this.$destroy() }, methods: { // ... } }
阅读更多$destroy完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。
这样就可以重新更新数据了
- vue - 组件间通信 之 中央事件总线bus
- 使用Vue开发网站之路2-多组件通信1(利用bus总线进行事件触发)
- vue-bus非父子组件之间触发事件
- Vue 使用Props属性实现父子组件的动态传值
- vue event bus 非父子组件间通信问题
- vue父子组件中传值
- Vue父子组件传值
- vue-cli bus组件之间传值
- 浅谈Vue2.0父子组件间事件派发机制
- vue中父子组件绑定事件
- Vue之2.x版本父子组件双向绑定事件
- vue基础语法以及父子组件如何相互传值
- 详解vue父子组件间传值(props)
- vue 父子组件传值
- Vue父子组件相互传值
- vue学习18:非父子组件间的传值(bus/总线/发布订阅者模式/观擦者模式)
- 浅谈vue父子组件怎么传值
- Vue总线Bus兄弟组件传参
- 深入理解Vue父子组件通讯的属性和事件