假設一個項目,首頁不需要登錄就可以直接進入,但是在首頁中有各種其他的模塊,這些模塊中,有些需要登錄權限,而有些則不需要登錄權限,所以在進入這些模塊的時候,我們都要判斷當前的登錄狀態,那么我們應該怎么組織這一部分代碼呢?
在每一個需要登錄狀態的組件內,進行單獨判斷?
如果需要判斷登錄狀態的模塊比較少,也就是單獨的組件很少,其實也無所謂,但是如果有10個、8個的模塊需要判斷登錄狀態呢?每個組件內部,判斷一次?雖然代碼都一樣,也就是合並復制粘貼一下,但是,這是不是一種浪費,這時,就是mixins混入大展身手的時候了。
vue官方文檔上說:
混入 (mixins) 是一種分發 Vue 組件中可復用功能的非常靈活的方式。混入對象可以包含任意組件選項。當組件使用混入對象時,所有混入對象的選項將被混入該組件本身的選項。
單獨定義一個mixin的文件,使用ES6模塊方式,將其定義成一個完整的模塊。假設文件名為mixin.js。
export default { data() { return { msg: "這現在都可以這么玩了么?" } }, mounted() { let loginState = window.localStorage.getItem("loginState"); console.log(loginState) // 依賴loginState的結果進行不同的邏輯操作,或者路由跳轉 } }
這就是共用代碼部分的mixin即可:
import mixin from "./mixin" export default { mixins: [mixin], // 組件內其他邏輯操作代碼 data(){ return {} }, methods:{}, mounted(){} ... }
如果還有其他需要混入的部分,用相同的方法引入即可,然后將引入的對象添加到mixins這個屬性值的數組里面,數組的先后順序決定了他們的執行順序,比如都有mounted這個方法的話,就按mixins數組的先后順序執行,最后才執行組件內部的mounted。
當組件和混入對象含有同名選項時,這些選項將以恰當的方式混合。 比如,數據對象在內部會進行淺合並 (一層屬性深度),在和組件的數據發生沖突時以組件數據優先。 值為對象的選項,例如 methods, components 和 directives,將被混合為同一個對象。兩個對象鍵名沖突時,取組件對象的鍵值對。
就是說methods, components 和 directives這些個屬性當中,如果有與mixin中對象的鍵名沖突了,那使用的是組件內部的鍵值。
export default { data() { return { msg: "這現在都可以這么玩了么?" } }, methods: { whyClick() { console.log("why dispatch click, what would you like todo?") } }, mounted() { let loginState = window.localStorage.getItem("loginState"); console.log(loginState) // 依賴loginState的結果進行不同的邏輯操作,或者路由跳轉 } }
而同時,在引入該mixin的組件內部的methods中,也有whyClick這一方法
export default { mixins: [mixin], data (){ return { // msg: "我就想看看這個mixin當中的this指向哪里?" } }, methods:{ whyClick(){ console.log("I just click, and test it, not OK ?") } }, ... }
此時,在組件中
<button @click="whyClick">whyClick, don't you kow?</button>
那么只會執行組件內部的whyClick方法,而不會執行mixin中的whyClick。
mixin不僅可以組件內局部混入,也可以全局混入。
Vue.mixin({ ... })
在這里需要提示注意的一點是:全局混入,即Vue.mixin({})需要寫在new Vue({})之前,包括Vue.filter(), Vue.directive()也是如此,就是說所有全局定義的,需要在vue實例構造之前定義。
vue為我們定義了一整套選項合並的策略,但是總有一些特殊需求,需要一些特殊的合並策略,vue同時提供了自定義選項合並策略。
自定義選項將使用默認策略,即簡單地覆蓋已有值。如果想讓自定義選項以自定義邏輯合並,可以向 Vue.config.optionMergeStrategies 添加一個函數:
Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) { // return mergedVal }
更多復雜的合並策略可以翻看其官方文檔自定義選項合並策略。