Problem description : Recently, I encountered a scene when I was doing the login part , When clicked
“ user ” Button time , Render first login assembly , Jump to user information interface directly after user login (user assembly ). There is a need to login The user information obtained by the component through asynchronous request is transmitted to
user assembly , however login and login Component is not a parent-child component , It's called brother component for the time being . In short , What I want to solve is the problem of information transfer between brother components .


// be located login.vue in export default { methods:{ login(){ this.$axios({ method:
'post', url: '/student/login/', data: { username: this.username, password:
this.password } }) .then(function (response) { this.$router.replace({path:
'user'}); }.bind(this)) .catch(function (error) { console.log(error);
alert(' Wrong user name or password '); }); } } }
After the asynchronous request is completed , Jump to user In components , however response The request return information of cannot be passed to the non parent-child component user In components .



.............................................................................................................................................................................................................

solve the problem :

One , First of all, I thought of login assembly and user Put components together ( Two components combined 2 by 1), Avoid information transfer between components , But this solution is too low, Destroy the original structure of the project .

Two , I found out from the documents


Communication is also required between two components of a non parent-child relationship . In a simple scenario , You can use an empty Vue Instance as event bus : var bus = new Vue() // Trigger component A
Events in bus.$emit('id-selected', 1) // In components B Listening events in the created hook bus.$on('id-selected',
function (id) { // ... }) Take my own problems as an example , Write specific implementation :(warning:   My own situation can't be solved in this simple way )


It's better to create a new one first js file , To create our eventBus, We call it bus.js


import Vue from 'vue'; export default new Vue(); And then login.vue In file :



// be located login.vue in import Bus from '../bus.js'; export default { methods:{
login(){ this.$axios({ method: 'post', url: '/student/login/', data: {
username: this.username, password: this.password } }) .then(function (response)
{ /* * there 'login-on' Yes Bus A self constructed event in ( There's no need to state it elsewhere ), adopt emit() function *
Trigger this event manually , And then user.vue You can listen to this event in , Once an event is found, it triggers , You can use it * Callback function receive response This object , Achieve the purpose of information transmission
* */ Bus.$emit('login-on',response); this.$router.replace({path: 'user'});
}.bind(this)) .catch(function (error) { console.log(error); alert(' Wrong user name or password ');
}); } } } stay user.vue In file :// be located user.vue in import Bus from '../bus.js'; export
default { mouted : { Bus.$on('login-on', message => { //
there message From login.vue Data from console.log(message); }); } } This completes the data transfer .


But it was found during the test that user.vue Component monitoring Not triggered

analysis : In the situation I met ,login.vue Components and user.vue
Components are substitutes , I.e. from login Components pass vue-router Jump to user assembly , stay login.vue Destroy before rendering user.vue assembly , So in user.vue In
Bus.$on('login-on', message => Listening starts after events and triggers , Callback function will not be generated naturally .


From this we can see that , Officially recommended eventbus The flaw in the solution is , During data transfer , Both components must have been rendered . In my situation , This method is not applicable .

Three ,vuex Solution :
be familiar with vuex Please skip it .

It's better to src Create a new file in the root directory of , call store.js


// be located store.js in import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex);
export default new Vuex.Store({ /* * state It refers to the stored data , * The following data are the data fields I need to use in my project * */
state: { has_login: false, id: 1, mobile_num: '', name: '' }, /* *
mutations It's about changing state( data ) Action function of , * Below user_message It's what I'm going to introduce message Assigned to *
state Data fields , To update data * */ mutations: { user_message (state, message) {
state.has_login = true; state.id = message.data.id; state.mobile_num =
message.data.mobile_num; state.name = message.data.name; } } })


And then login.vue In components , Submit received user information


// be located login.vue in import userMessage from '../store'; export default new
Vuex.Store({ methods: { loginSubmit () { this.$axios({ method: 'post', url:
'/student/login/', data: { username: this.username, password: this.password }
}) .then(function (response) { // Call here store.js in
mutations Inside user_message function , To change the state data userMessage.commit('user_message',
response); this.$router.replace({path: 'user'}); }.bind(this)) .catch(function
(error) { console.log(error); alert(' Wrong user name or password '); }); } })
At last user.vue Received in component vuex Information stored in the warehouse , That is, to import the warehouse first



// be located user.vue in import userMessage from '../store'; Then you can directly userMessage.state
Assign to user.vue Data fields in scope , meanwhile ,vuex Of state Properties with hot update , Useful for data synchronization , Many advantages .


therefore , Large and medium-sized projects are still directly used at the beginning vuex It's a wise decision , Great convenience for development .