In vue, eventbus is triggered by multiple triggers and pitfalls.
This is the first requirement. to transfer data between two page components, suppose I have page A and click A button on page, the page will automatically jump to page B, and I want to carry some parameters on page A to page B. (I know that when using small parameters, you can pass parameters through the route params or query, or you can use vuex to process large data, sorry, I haven't done a large project yet, so I haven't used vuex yet. I will study it later .)
Then I thought, isn't that just the problem of data transmission between different components? Just use bus events to transmit data. So I went on happily. For the use of eventbus in vue, I mentioned in a previous article about data transmission in vue.
Let's take a look at my first code:
Goals:
After clicking, the bus emit event will jump to the/moneyRecord page by the way.
Next, go to the MoneyRecord page to receive the event on and then accept the parameter.
// This is the code editList (index, date, item) that triggers the bus event on page A {// click to enter the editing page. Many parameters need to be passed. Console. log (index, date, item) bus. $ emit ('get', {item: item. type, date: date}) this. $ router. replace ({path: '/moneyRecord'})} // created () on the moneyRecord page {// here, I saved the list of icons to the bus. $ on ('get', this. myhandle)}, methods: {myhandle (val) {console. log (val, 'This is the parameter passed from the previous page ')}}
When I was ecstatic, I felt that as long as I triggered the get event on page A, page B would naturally accept the data. However, the results are not satisfactory. Let's look at the animation below.
The main difference is that "" is the number of output times of the Data row sent from the previous page to determine the number of event triggers. ""
I don't know if you have found out, that is, when I first went into the list page, I clicked any item under the list, and there was no output in the console. However, when I click the trigger event for the second time, a test data is output. Click again to output two pieces of data... In turn. (The "this is the data from the previous page" on the console is the test data)
Therefore, there are two problems.
Problem:
- Question 1: Why is the on event in page B not triggered when the first trigger?
- Question 2: Why does it appear when it is triggered again in sequence? Every time it appears as if the previous on Event distribution was not canceled, resulting in more and more triggering operations for each event.
Solution
For Question 1
This has to start with the vue life cycle. I tested it first, that is, what is the life cycle of the two components when I jump from page component A to page component B, I will not go into details about what to do in each specific period of the vue lifecycle. The following po shows the vue lifecycle.
I did an experiment to verify the implementation of the two components during the page Jump process.
// Add the following code in page A and page B: beforeCreate () {console. group ('% c % s', 'color: red ', 'beforecreate status ====================== component 2 ')}, created () {console. group ('% c % s', 'color: red ', 'created creation completion status ==================== component 2 ')}, beforeMount () {console. group ('% c % s', 'color: red ', 'beforemount status before mounting ==================== component 2 ')}, mounted () {console. group ('% c % s', 'color: red ', 'mounted mounting status ==================== component 2 ')}, beforeUpdate () {console. group ('% c % s', 'color: red ', 'beforeupdate status before update ==================== component 2 ')}, updated () {console. group ('% c % s', 'color: red ', 'updated Update Status ==================== component 2 ')}, beforeDestroy () {console. group ('% c % s', 'color: red ', 'beforedestroy status ==================== component 2 ')}, destroyed () {console. group ('% c % s', 'color: red', 'Destroy state ====================== component 2')} // I will not release another component
Test result diagram:
In fact, we can see from the results that when we are still on page A, page B has not yet been generated, that is, the event from A that is listened to in created in page B has not been triggered yet. In this case, B does not actually listen to the emit event in.
Let's look at the page B component in red. What happens when you jump from page A to page B? First, the B component is created first, then beforeMount, and then the component is destroyed, and the component executes beforeDestory and destoryed.
Therefore, we can write the emit event in the page component in beforeDestory. At this time, the B page component has been created, that is, the $ on event we wrote has been triggered.
So yes, $ emit event during beforeDestory.
// Modify the code on page A: // This is the original code editList (index, date, item) {// click to go to the editing page. Many parameters need to be passed. Console. log (index, date, item) this. item = item. type this. date = date this. $ router. replace ({path: '/moneyRecord'})} // define a new variable in the data attribute to store the data to be uploaded. Then: beforeDestroy () {console. log (this. highlight, 'This is the data of this year', this, 'Look at what will happen before the component is destroyed') bus. $ emit ('get', {item: this. item, date: this. date })},
Next. Let's take a look at the modified results.
It can be seen that when you click list for the first time, that is, when you trigger the emit event for the first time, the control is too output, so it plays a role in beforeDestoryed to go to $ emit, the page B component also listens for $ on.
However, it seems that the event triggers will increase sequentially, that is, the console output will increase every time...
Solution:
Let's take a look at the github proposal. Https://github.com/vuejs/vue/issues/3399
You have proposed the following solutions:
* That is to say, the $ on event will not be automatically destroyed, and we need to manually destroy it. (But I am not quite sure what external bus means here. Can you give me some answers? You mentioned that you need to clear the external bus when registering it )****
So. I added Bus. $ off to the B component page to disable the function. The Code is as follows:
// Add the following statement on the B component page to destroy the beforeDestory component. BeforeDestroy () {bus. $ off ('get', this. myhandle )},
Let's take a look at the output results.
T you can see that there is output when the console first enters, and the output will not increase
* Of course, can you write a mixin? I still don't know what it is? I will study it later.
Conclusion: If you want to use bus to transmit data between page components, pay attention to the highlights. component A $ emit events should be within the beforeDestory lifecycle. Second, remember to destroy $ on in component B.
Question Time: Do you have any good methods to transfer data between page components? Can I share a message? Sometimes it can be obtained from the backend, but considering that only a few data needs to be transferred, there is no need to request data. I know that some still use vueX for transmission. What else?
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.