vue非父子組件通信問題及解決方法
問題描述:
最近在做登錄部分時遇到一個場景,當點擊 “用戶”按鈕時,首先渲染login組件,在用戶登錄后直接跳轉(zhuǎn)到用戶信息界面(user組件)。這里遇到了需要將login組件通過異步請求獲得的用戶信息傳向 user組件,但是login和login組件不是父子組件,就暫稱為兄弟組件吧。 簡而言之,我要解決的就是兄弟組件之間的信息傳遞問題。
//位于login.vue 中 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('用戶名或密碼錯誤'); }); } } }
在異步請求完成后,就跳轉(zhuǎn)到user組件中,但是response的請求返回信息就無法傳到非父子組件的user組件中。
.............................................................................................................................................................................................................
解決問題:
一、首先我想到了將login組件 和 user組件放到一起(兩個組件合2為1),加避免了組件間的信息傳遞,但是這種解決方案太low,破壞了項目原有的結(jié)構(gòu)。
二、查文檔得知了
非父子關(guān)系的兩個組件之間也需要通信。在簡單的場景下,可以使用一個空的 Vue 實例作為事件總線:
var bus = new Vue() // 觸發(fā)組件 A 中的事件 bus.$emit('id-selected', 1) // 在組件 B 創(chuàng)建的鉤子中監(jiān)聽事件 bus.$on('id-selected', function (id) { // ... })
以自己遇到的問題為例,寫出具體的實現(xiàn):(warning: 我自己遇到的情況不能用這種簡單的方式解決)
最好先新建一個js文件,來創(chuàng)建出我們的eventBus,我們把它命名為bus.js
import Vue from 'vue'; export default new Vue();
然后在 login.vue 文件中:
//位于login.vue 中 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) { /* * 這里的 'login-on'是在Bus中自己構(gòu)造的一個事件(不需要在別處申明),通過emit()函數(shù) * 手動觸發(fā)這個事件,然后在user.vue 中可以監(jiān)聽這個事件,一旦發(fā)現(xiàn)事件觸發(fā),就可以利用 * 回調(diào)函數(shù)接收 response 這個對象,達到信息傳遞的目的 * */ Bus.$emit('login-on',response); this.$router.replace({path: 'user'}); }.bind(this)) .catch(function (error) { console.log(error); alert('用戶名或密碼錯誤'); }); } } }
在user.vue文件中:
//位于user.vue 中 import Bus from '../bus.js'; export default { mouted : { Bus.$on('login-on', message => { // 這里的message就是從login.vue中傳來的數(shù)據(jù) console.log(message); }); } }
這樣就完成了數(shù)據(jù)傳遞。
但是在測試時發(fā)現(xiàn)在user.vue組件的監(jiān)聽 沒有被觸發(fā)
分析:在我遇到的情境中,login.vue組件和user.vue 組件是互相替代的關(guān)系,即需要從login組件通過vue-router跳轉(zhuǎn)到user組件,在login.vue銷毀后才開始渲染user.vue組件,所以在user.vue中的
Bus.$on('login-on', message =>
監(jiān)聽是在事件以及觸發(fā)之后才開始,自然不會產(chǎn)生回調(diào)函數(shù)。
由此可以看出,官方推薦的eventbus 解決方案的缺陷在于, 在數(shù)據(jù)傳遞過程中,兩個組件必須都已經(jīng)被渲染過。我的這種情景下,這種方法不適用。
三、vuex解決方案:
熟悉vuex的大佬們請直接跳過吧。
最好在src的根目錄下新建一個文件,叫 store.js
//位于store.js 中 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); export default new Vuex.Store({ /* * state指的就是儲存的數(shù)據(jù), * 下面的數(shù)據(jù)是我在項目中需要用的數(shù)據(jù)字段 * */ state: { has_login: false, id: 1, mobile_num: '', name: '' }, /* * mutations里面規(guī)定的就是想要改變state(數(shù)據(jù))的動作函數(shù), * 下面的user_message 就是我將傳入的message賦值給倉庫中的 * state數(shù)據(jù)字段,達到更新數(shù)據(jù)的目的 * */ 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; } } })
然后在login.vue組件中,提交收到的用戶信息
//位于login.vue 中 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) { //這里調(diào)用 store.js中 mutations里面的user_message函數(shù),從而改變倉庫中的state數(shù)據(jù) userMessage.commit('user_message', response); this.$router.replace({path: 'user'}); }.bind(this)) .catch(function (error) { console.log(error); alert('用戶名或密碼錯誤'); }); } })
最后在user.vue組件中接收vuex倉庫中存儲的信息,即先引入倉庫
//位于user.vue 中 import userMessage from '../store';
然后可以直接將 userMessage.state 賦值給user.vue作用域中的數(shù)據(jù)字段,同時,vuex 的state有熱更新的屬性,對于數(shù)據(jù)的同步很有幫助,優(yōu)點良多。
所以,中大型的項目還是在一開始就直接使用vuex是明智的決定,對于開發(fā)有很大的便利。
總結(jié)
以上所述是小編給大家介紹的vue非父子組件通信問題解決方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
vue-quill-editor+plupload富文本編輯器實例詳解
這篇文章主要介紹了vue-quill-editor+plupload富文本編輯器實例詳解,需要的朋友可以參考下2018-10-10vue、uniapp實現(xiàn)組件動態(tài)切換效果
在Vue中,通過使用動態(tài)組件,我們可以實現(xiàn)組件的動態(tài)切換,從而達到頁面的動態(tài)展示效果,這篇文章主要介紹了vue、uniapp實現(xiàn)組件動態(tài)切換,需要的朋友可以參考下2023-10-1015 分鐘掌握vue-next函數(shù)式api(小結(jié))
這篇文章主要介紹了15 分鐘掌握vue-next函數(shù)式api(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10解決vue-router中的query動態(tài)傳參問題
下面小編就為大家分享一篇解決vue-router中的query動態(tài)傳參問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03