In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces the vue in the eventBus will produce memory leaks, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let the editor with you to understand.
EventBus is often used in vue to solve the problem of cross-component messaging, but pay special attention to its use, otherwise it will have serious consequences.
Introduce
This article introduces the implementation principle of eventBus, introduces how to use it in vue, and gives a concrete example to illustrate that if used improperly, it can cause memory leakage.
Note that eventBus is not a front-end concept.
Contributed by the greenrobot [1] organization (which also contributed greenDAO), an Android event publish / subscribe lightweight framework
Function: simplify Android event delivery by decoupling publishers and subscribers [2]
EventBus can replace Android's traditional Intent,Handler,Broadcast or interface functions to transfer data between Fragment,Activity,Service threads and execute methods.
Features: concise code, is a publish and subscribe design pattern (observer design pattern).
Content
Implementation of eventBus in vue
Using eventBus in vue
Improper use: multiple callbacks; memory leaks
Solution: call $off in time
Implementation of eventBus in vue
EventBus means event bus, which is essentially a release subscriber implementation. In vue2.X, $on,$emit,$off is provided on the vue instance to add observers, publish events, and unsubscribe, respectively.
Therefore, we can directly attach a vue instance to the prototype of Vue to act as an intermediary for components to communicate with each other.
Vue.prototype.$eventBus = new Vue ()
In this way, all Vue components can find this $eventBus along the prototype chain, thus accessing $on, $off,$emit.
It can help us achieve cross-component communication.
Example: using eventBus
Publish events in the root component and listen for events in two subcomponents.
The basic use of eventBus is Vue.prototype.$eventBus = new Vue () Vue.component ('com1', {template: `com1`, created () {this.$eventBus.$on (' event1', function F1 (d) {conse.log (d, 'com1 listen...) Event1')})},}) Vue.component ('com2', {template: `com2`, created () {this.$eventBus.$on (' event2', function f2 (d) {conse.log (d, 'com2 listen...) Event2')}) var vm = new Vue ({el:'# app', created () {setInterval () = > {const d = Date.now () this.$eventBus.$emit ('event1', d) this.$eventBus.$emit (' event2', d)}, 3000)}))
When creating com1 components, subscribe to event1 events; when creating com2 components, subscribe to event2 events; when creating root components (vue instances), start the timer: publish events every 3 seconds, so that both com1 and com2 can receive events and execute corresponding callbacks.
The effect is as follows:
Example: unsubscribe not in time
If the subscription is not unsubscribed in time, the callback function will still execute, and more seriously, if an external variable is referenced in the event handling callback function to form a closure, it will result in a memory leak.
The following code illustrates this problem.
In the root component (vue instance), add a data item showCom1 and configure the v-if directive to destroy and rebuild the com1 component.
The problem of not canceling subscription in time {{showCom1? "destroy": "rebuild"} component 1 Vue.prototype.$eventBus = new Vue () Vue.component ('com1', {template: `com1`, created () {conse.log (' create com1') this.$eventBus.$on ('event1', function F1 (d) {conse.log (d,' com1 listen...) Event1')}) Vue.component ('com2', {template: `com2`, created () {this.$eventBus.$on (' event2', function f2 (d) {conse.log (d, 'com2 listen...) Event2')}) var vm = new Vue ({el:'# app', data: {showCom1: true}, created () {setInterval () = > {const d = Date.now () this.$eventBus.$emit ('event1', d) this.$eventBus.$emit (' event2', d)}, 3000)}))
Let's start with a question: do you think that after the com1 component is destroyed, the event1 events it subscribes to in created will still be received? Can the corresponding callback function be executed again? The general idea is that if the components are destroyed, then the events it subscribes to must not be received.
The answer is: it can still be received. The reason is simple: event subscription is done by the $eventBus object and has nothing to do with the com1 component.
The effect of the above code execution is as follows:
After destroying component 1, it can also receive the event1 event normally and perform a callback
When component 1 is created again, it subscribes to the event1 event again, so the result is two callbacks.
Next, let's explain the problem of memory leak. Change the component content of com1 to the following:
Vue.component ('com1', {template: `com1`, created () {console.log (' create com1') let m = 1`1024 * 1024 let arr = new Array (m) .fill ('a') this.$eventBus.$on ('event1', function F1 (d) {/ / notice that there is a closure console.log (d,' com1 listen... event1', arr [1])})})
Refer to the variable arr outside the function in the callback function F1, where there is a closure.
Add a snapshot to the memory in the browser's debugging tool and view the results as follows:
Then, click "destroy component 1" on the page, add a snapshot again, and you will find that the space has not been released.
The explanation is as follows:
The above is a schematic diagram of this process. Because the F1 subscription was not unsubscribed in time, the arr array was not released.
Solution:
In the destoryed hook of com1, call $off to unsubscribe.
Destroyed () {/ / cancel all listening to event1 events this.$eventBus.$off ('event1')}
The debugging results are as follows:
It can be seen that after the com1 is deleted, the space for this number is freed, and its event listener function will no longer be executed.
Other considerations
The format of $off:
$off () cancels all event subscriptions
$off ('event name') unspecifies the name of the event
$off ('event name', callback) will cancel the specified event name and specify the callback
The difference between created and mounted of parent and child components, in order of execution:
The created of the parent component precedes the created of the child component
The mounted of the parent component precedes the mounted of the child component
So, it depends on which hook to subscribe and which hook to publish.
Thank you for reading this article carefully. I hope the article "will eventBus in vue cause memory leaks" shared by the editor will be helpful to everyone? at the same time, I also hope that you will support and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.