We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
https://escawn.github.io/(已废弃)
eventBus是一个vue实例,上面挂载了许多监听事件,通过触发相应的监听事件,可以实现不同层级的组件之间的通信。
eventBus是为小型项目等组件层级不深,状态不复杂的项目提供的组件通信方案,它本质上可以看做是一个挂载了许多事件的vue实例,在所需组件中引入这个实例,以此为桥梁,触发不同层级组件中监听的事件。
// 单独声明一个eventBus.js,里面仅需声明一个vue实例 // eventBus.js import vue from "vue" const eventBus = new Vue({}) export default eventBus // componentA import eventBus from './eventBus.js' export default { // 此处省略n行代码 methods: { func(params) { console.log('组件A的被触发了,' + '参数为:' + params) } }, mounted: function(){ this.$nextTick(function(){ eventBus.$on('message', (params) => this.func(params)) }) } } // componentB import eventBus from './eventBus.js' export default { // 在组件B mounted时触发事件A中事件 mounted: function(){ this.$nextTick(function(){ eventBus.$emit('message', ('hhhhhh')) }) } } // 组件A的message被触发了,参数为:hhhhh
// componentA <script> import Vue from 'vue' export default { data() { return { eventBus: new Vue({}) } }, methods: { func(params) { console.log('组件A的被触发了,' + '参数为:' + params) } }, mounted: function(){ this.nextTick(function(){ this.eventBus.$on('message', (params) => this.func(params)) }) } } </script> <template> <!-- 此处省略n行代码 --> <component-b :event-bus="eventBus"></component-b> </template> // componentB export default { props: { eventBus: { type: Object } }, // 在组件B mounted时触发事件A中事件 mounted: function(){ this.$nextTick(function(){ this.eventBus.$emit('message', ('hhhhhh')) }) } }
可以看到,在组件中创建eventBus的方式适用于有直接嵌套关系,并且层级不深的组件,比如父子组件(但是明显父子组件之间有更加便捷的通信方式)。一旦涉及层级较深,事件较多的情形(但是又没复杂到需要使用vuex的地步),我们会采用单文件eventBus直接引入的方式。这样的方式会带来一些隐藏的陷阱,接下来会一一提到。
官方文档 >
. ├── componentA.vue ├── componentB.vue └── eventBus.js
routes: [ { path: '/componentA', name: 'componentA', component: componentA }, { path: '/', redirect: { path: '/componentA' } }, { path: '/componentB', name: 'componentB', component: componentB } ]
mounted
$on
message
$emit
beforeDestroy
在组件A和组件B之间通过路由切换时,点击组件B内按钮,正常触发message事件
说明:在第二次从组件A切换到组件B时,点击按钮,出现了两次'message'事件被触发的效果,当组件A第N次切换到组件B时,点击按钮,出现了N次'message'事件被触发的效果
组件的销毁不能使eventBus里的事件销毁。并且当组件再次创建时,同名事件不覆盖,会被再次注册绑定。导致看起来是多次触发了同一事件,实际上是同时触发了多个同名事件。
做法:在组件A的beforeDestroy周期,解绑事件
beforeDestroy: function(){ eventBus.$off('message') }
结果:达到期望结果 解决推测:组件销毁时事件没被销毁
做法:增加一个父组件componentParent,在父组件中声明eventBus,并以prop方式传递给组件A和组件B,在组件A销毁时销毁 结果:达到期望结果 解决推测:事件不销毁是挂载的eventBus没被销毁导致的
做法:在组件A内绑定一个同名事件message
// componentA mounted: function(){ this.$nextTick(function(){ eventBus.$on('message', (params) => this.func(params)) ); eventBus.$on('message', () => console.log('再次绑定了message事件')); }) }
结果:点击按钮时,console.log两次,说明两个事件都被触发了。 解决推测:同名事件不会被覆盖
console.log
做法:在组件A和组件B的<router-view>前增加<keep-alive>标签,保持组件在路由切换时不被销毁 结果:达到期望结果 解决推测:组件销毁-创建会重复注册事件
<router-view>
<keep-alive>
由以上实践可知
事件解绑是必要的,之前写代码没有这方面的意识,这次踩坑发现了,写代码要严谨,考虑清楚在组件的各个声明周期内要做什么。
The text was updated successfully, but these errors were encountered:
我也遇到了
Sorry, something went wrong.
No branches or pull requests
https://escawn.github.io/(已废弃)
eventBus是一个vue实例,上面挂载了许多监听事件,通过触发相应的监听事件,可以实现不同层级的组件之间的通信。
eventBus简介
eventBus是为小型项目等组件层级不深,状态不复杂的项目提供的组件通信方案,它本质上可以看做是一个挂载了许多事件的vue实例,在所需组件中引入这个实例,以此为桥梁,触发不同层级组件中监听的事件。
基础用法
单独的eventBus文件
组件中声明
可以看到,在组件中创建eventBus的方式适用于有直接嵌套关系,并且层级不深的组件,比如父子组件(但是明显父子组件之间有更加便捷的通信方式)。一旦涉及层级较深,事件较多的情形(但是又没复杂到需要使用vuex的地步),我们会采用单文件eventBus直接引入的方式。这样的方式会带来一些隐藏的陷阱,接下来会一一提到。
异常触发事件
文档结构&场景
文档结构
路由
行为描述
mounted
时,在eventBus上$on
一个message
事件$emit
eventBus上的message
事件beforeDestroy
的声明周期内打出相应讯息期望结果
在组件A和组件B之间通过路由切换时,点击组件B内按钮,正常触发
message
事件实际结果
说明:在第二次从组件A切换到组件B时,点击按钮,出现了两次'message'事件被触发的效果,当组件A第N次切换到组件B时,点击按钮,出现了N次'message'事件被触发的效果
推测
组件的销毁不能使eventBus里的事件销毁。并且当组件再次创建时,同名事件不覆盖,会被再次注册绑定。导致看起来是多次触发了同一事件,实际上是同时触发了多个同名事件。
实验
解绑事件
做法:在组件A的beforeDestroy周期,解绑事件
结果:达到期望结果
解决推测:组件销毁时事件没被销毁
非全局eventBus使用
做法:增加一个父组件componentParent,在父组件中声明eventBus,并以prop方式传递给组件A和组件B,在组件A销毁时销毁
结果:达到期望结果
解决推测:事件不销毁是挂载的eventBus没被销毁导致的
同名事件
做法:在组件A内绑定一个同名事件
message
结果:点击按钮时,
console.log
两次,说明两个事件都被触发了。解决推测:同名事件不会被覆盖
keep-alive的影响
做法:在组件A和组件B的
<router-view>
前增加<keep-alive>
标签,保持组件在路由切换时不被销毁结果:达到期望结果
解决推测:组件销毁-创建会重复注册事件
总结
由以上实践可知
反思
事件解绑是必要的,之前写代码没有这方面的意识,这次踩坑发现了,写代码要严谨,考虑清楚在组件的各个声明周期内要做什么。
The text was updated successfully, but these errors were encountered: