在開發的時候,經常會涉及到組件之間的通信。簡單的有父子組件的通信,兄弟組件的通信通常可以借助Bus來進行。當然也可以用vuex來進行狀態管理,但是,有時候用vuex未免有把簡單的問題復雜化。
如果要進行狀態管理的話,比如要存取用戶信息,這時候可以利用 Vue.js 2.2.0 版本后新增的 API provide/inject來寫,詳細看文檔
https://cn.vuejs.org/v2/api/#provide-inject
用法就是在一個組件中provide一個屬性,另一個組件inject,就可以在這個組件中訪問前面組件的屬性
// A.vue export default { provide: { title: 'Hello World' } } // B.vue export default { inject: ['title'], mounted () { console.log(this.name); //Hello World
}
}
需要注意的是:
provide 和 inject 綁定並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的對象,那么其對象的屬性還是可響應的。
就是說如果A.vue的title屬性變化了,B組件里的title是不變的,還是Hello World
用這個來替代vuex,存取用戶信息
app.vue 是整個項目第一個被渲染的組件,而且只會渲染一次(即使切換路由,app.vue 也不會被再次渲染),利用這個特性,很適合做一次性全局的狀態數據管理,例如,我們將用戶的登錄信息保存起來:
provide / inject API 主要解決了跨級組件間的通信問題,不過它的使用場景,主要是子組件獲取上級組件的狀態,跨級組件間建立了一種主動提供與依賴注入的關系。
app.vue 提供userInfo信息
export default { provide () { return { app: this } }, data () { return { userInfo: null } }, methods: { getUserInfo () { // 這里通過 ajax 獲取用戶信息后賦值 $.ajax('/userinfo', (data) => { this.userInfo = data; }); } }, mounted () { this.getUserInfo(); } }
這樣,任何頁面都可以訪問userInfo
<template> <div> {{ app.userInfo }} </div> </template> <script> export default { inject: ['app'], created(){ console.log(this.app.userInfo); } } </script>
除了直接使用數據,還可以調用方法。比如在某個頁面里,修改了個人資料,這時一開始在 app.vue
里獲取的 userInfo
已經不是最新的了,需要重新獲取。
export default { inject: ['app'], methods: { changeUserInfo () { // 這里修改完用戶數據后,通知 app.vue 更新,以下為偽代碼 $.ajax('/updateuserinfo', () => { // 直接通過 this.app 就可以調用 app.vue 里的方法 this.app.getUserInfo(); }) } } }
參考:https://juejin.im/book/5bc844166fb9a05cd676ebca/section/5bc845435188255c533655f4