當前位置:
首頁 > 科技 > 在Vue.js中使用Mixins

在Vue.js中使用Mixins

前言

今日早讀文章由 @ 池盛星翻譯投稿分享。

正文從這開始~

一個很常見的場景: 你有兩個非常相似的組件, 它們擁有非常相似的基本功能, 但是它們之間又有足夠的不同的地方, 該如何選擇呢? 我們是應該將它們分成兩個完全不同的組件呢? 還是創建一個基礎組件, 然後定義足夠多的props以方便區分使用場景?

這兩種方式都不是完美的: 如果你將它們分成兩個完全不同的組件, 在需求變化(功能變化)時, 可能會增加需要同時修改兩個組件的風險, 這違反了"DRY"的前提. 另一方面, 太多的props很快會讓人變得凌亂, 並且, 迫使維護人員, 甚至是你自己, 要首先理解這些props的上下文才能使用它, 這會讓人非常失望.

Vue的Mixins是非常實用的編程方式, 因為最終實用的編程是通過不斷減少運動部件(moving parts)使代碼變得容易理解. (關於這一點, Michael Feathers有一個很好的引用). 一個mixin允許你封裝一個功能, 以便你能在整個應用程序中的不同組件中使用它. 如果mixin被正確的創建, 它們是純粹的--它們不會修改或更改函數的作用範圍(scope)之外的內容, 因此, 您可以在多個地方執行它們, 並且只要輸入值相同, 總是能非常可靠得得到相同的結果. 這真的非常強大.

基本的例子

假設我們有一些不同的組件, 它們的工作是切換狀態boolean, 一個模態(modal)和一個提示(tooltip). 這些tooltips和modals沒有很多共同之處, 除了這個功能: 它們看起來不一樣, 它們使用起來也不盡相同, 但是它們的邏輯是相似的 .

//modal

constModal={

template: #modal ,

data(){

return{

isShowing:false

}

},

methods:{

toggleShow(){

this.isShowing=!this.isShowing;

}

},

components:{

appChild:Child

}

}

//tooltip

constTooltip={

template: #tooltip ,

data(){

return{

isShowing:false

}

},

methods:{

toggleShow(){

this.isShowing=!this.isShowing;

}

},

components:{

appChild:Child

}

}

我們可以從中提取邏輯, 並創建可以復用的部分:(在CODEPEN中查看效果)

consttoggle={

data(){

return{

isShowing:false

}

},

methods:{

toggleShow(){

this.isShowing=!this.isShowing;

}

}

}

constModal={

template: #modal ,

mixins:[toggle],

components:{

appChild:Child

}

};

constTooltip={

template: #tooltip ,

mixins:[toggle],

components:{

appChild:Child

}

};

這個例子有意保持小而簡單, 是我找到的在實際的應用程序中非常有用的關於mixins的易讀的例子包括但不限於: 獲取viewport和組件的維度, 收集特定的mousemove events, 以及基本的圖表元素. Paul Pflugradt有一個非常不錯的關於Vue Mixins的repo, 值得注意的是, 它們是用coffeescript所寫的.

使用

這個Pen並沒有真正的告訴我們如何在一個真正的應用程序中設置它, 所以, 讓我們來看看:

您可以設置您的目錄結構以任何您喜歡的方式, 但我喜歡創建一個單獨的mixin目錄以方便管理它們. 我們將創建的文件將具有".js"擴展名(而不是.vue, 就像我們其他的文件), 然後我們將導出(export)一個對象為mixin:

然後, 在modal.vue里, 我們可以通過import剛才的toggle來訪問它, 就像這樣:

importChildfrom ./Child

import{toggle}from ./mixins/toggle

exportdefault{

name: modal ,

mixins:[toggle],

components:{

appChild:Child

}

}

很重要的需要意識到的一點是, 儘管如此, 我們使用的是一個對象(object)而不是一個組件(component), 生命周期(lifecycle)內的方法(methods)是可用的. 我們可以掛載(hook)到mounted(), 這樣它就會被應用於組件的生命周期, 使得這種方法非常的靈活和強大.

合并(Merging)

看看最後一個例子, 我們發現, 我們不僅僅擁有我們的功能, 生命周期的鉤子(hooks)也可用於mixin, 所以, 當我們將它應用與具有重疊進程(overlapping processes)的時候, 順序很重要. 默認情況下, mixins將首先被調用, 然後是組件, 所以我們可以根據需要來覆蓋它(override). 就是說, 組件有最後的發言權. 這隻有當衝突發生時才變得非常重要, 在這個時候, 組件必須決定哪一個勝出, 否則一切將被放置在一個數組中執行, mixins相關的放在前面, 然後是組件相關的 .

//mixin

consthi={

mounted(){

console.log( hello from mixin! )

}

}

//vue instance or component

newVue({

el: #app ,

mixins:[hi],

mounted(){

console.log( hello from Vue instance! )

}

});

//Output in console

>hellofrommixin!

>hellofromVue instance!

如果兩個衝突, Vue實例和組件將勝出:

//mixin

consthi={

methods:{

sayHello:function(){

console.log( hello from mixin! )

}

},

mounted(){

this.sayHello()

}

}

//vue instance or component

newVue({

el: #app ,

mixins:[hi],

methods:{

sayHello:function(){

console.log( hello from Vue instance! )

}

},

mounted(){

this.sayHello()

}

})

// Output in console

>hellofromVue instance!

>hellofromVue instance!

您可能已經注意到, 在Vue實例中, 我們有兩個console.log列印而不是一個. 這是因為, mixin解析以後, 在Vue實例中的mounted()裡面會有兩個this.sayHello()調用, 但是由於mixin中的sayHello函數會在Vue實例的sayHello函數之前, 因此被Vue實例中的sayHello函數覆蓋了. 所以, mounted()中調用的兩次sayHello實際上都是Vue實例中的sayHello函數.

全局Mixins

當我們使用術語global參考mixins時, 我們不是指能夠在每個組件訪問它們, 就像過濾器一樣. 我們已經可以在組件中訪問mixins以這種方式: mixins: [toggle].

Global mixins如字面上的意思一樣, 會被應用於所有的組件. 因此, 它們的用例非常有限, 應該慎重考慮. 我可以想到的能夠合理使用的一個場景是像插件一樣的東西, 你可能需要訪問一切. 但是, 即使在這種情況下, 我也會對您正在應用的內容感到擔心, 特別是當您將功能擴展到可能是黑匣子的應用程序時.

要創建全局實例, 我們將其放在Vue實例之前. 在典型的Vue-cli構建中, 這將在您的main.js 文件中 .

Vue.mixin({

mounted(){

console.log( hello from mixin! )

}

})

newVue({

...

})

還是那句話, 謹慎使用這種方式的mixin! 現在, mixin中的console.log將會出現在每一個單獨的組件中. 在這種情況下還不是很糟(除了控制台裡面多了許多噪音外). 但是您會發現, 如果使用不當, 將會帶來多大的危害.

結論

Mixins對於封裝一些可復用的功能非常實用. 它們當然不是您唯一可用的選項: 高階組件(higher order components), 例如, 允許您組合類似的功能, 這只是一種工作方式. 我喜歡mixins, 是因為我們不需要到處傳遞狀態(state), 但是, 這種模式當然也可以被濫用, 所以請仔細考慮哪個選項對您的應用程序是最有意義的 .

關於本文

譯者:@池盛星

作者:@sdrasner

原文:https://css-tricks.com/using-mixins-vue-js

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端早讀課 的精彩文章:

晉陞評審的套路
螞蟻金服招聘高級前端開發工程師/前端開發專家
正則表達式回溯法原理
SVG 新司機開車指南
webpack正式發布v3.0.0

TAG:前端早讀課 |

您可能感興趣

Vue+VueRouter+elememntUI+axios 搭建後台管理系統
GitHub趨勢:Vue.js大有超過TensorFlow之勢!
Vue: scoped 樣式與 CSS Module 對比
教你使用Vue.js的DevTools來調試你的vue項目
Vue中的methods、watch、computed的區別
Angular和Vue.js 深度對比
node+express+mongoDB寫簡單介面,Vue獲取介面
簡單理解Vue中的nextTick
Angular、React 當前,Vue.js 優劣幾何?
Vue.js 為何能逆襲 Angular 和 React 而主導前端?
Vue-SSR之Nuxt.js 在斗米 B 端實戰
dotnet core webapi+vue 搭建前後端完全分離web架構(一)
少女歌劇Revue Starlight-ReLIVE特別舞台
揚我國威!Bellevue新晉中餐Fine Dining,完全不輸西餐
揚我國威!Bellevue新晉中餐Fine Dining,完全不輸西餐
PicGo—基於 electron-vue 的炫酷圖床工具
.NET Core + Vue.js動態許可權(RBAC)管理系統框架「DncZeus」開源了
Per.js速度對比Vue.js
「少女歌劇Revue Starlight-ReLIVE」特別舞台報道
springboot+vue簡單的後台管理