自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在Vue.js中使用Mixin

開發(fā) 前端
Vue 中的Mixin對(duì)編寫函數(shù)式風(fēng)格的代碼很有用,因?yàn)楹瘮?shù)式編程就是通過減少移動(dòng)的部分讓代碼更好理解(引自 Michael Feathers )。Mixin允許你封裝一塊在應(yīng)用的其他組件中都可以使用的函數(shù)。

有一種很常見的情況:有兩個(gè)非常相似的組件,他們的基本功能是一樣的,但他們之間又存在著足夠的差異性,此時(shí)的你就像是來到了一個(gè)分岔路口:我是把它拆分成兩個(gè)不同的組件呢?還是保留為一個(gè)組件,然后通過props傳值來創(chuàng)造差異性從而進(jìn)行區(qū)分呢?

兩種解決方案都不夠***:如果拆分成兩個(gè)組件,你就不得不冒著一旦功能變動(dòng)就要在兩個(gè)文件中更新代碼的風(fēng)險(xiǎn),這違背了 DRY 原則。反之,太多的props傳值會(huì)很快變得混亂不堪,從而迫使維護(hù)者(即便這個(gè)人是你)在使用組件的時(shí)候必須理解一大段的上下文,拖慢寫碼速度。

使用Mixin。Vue 中的Mixin對(duì)編寫函數(shù)式風(fēng)格的代碼很有用,因?yàn)楹瘮?shù)式編程就是通過減少移動(dòng)的部分讓代碼更好理解(引自 Michael Feathers )。Mixin允許你封裝一塊在應(yīng)用的其他組件中都可以使用的函數(shù)。如果使用姿勢得當(dāng),他們不會(huì)改變函數(shù)作用域外部的任何東西,因此哪怕執(zhí)行多次,只要是同樣的輸入你總是能得到一樣的值,真的很強(qiáng)大!

基礎(chǔ)實(shí)例

我們有一對(duì)不同的組件,它們的作用是通過切換狀態(tài)(Boolean類型)來展示或者隱藏模態(tài)框或提示框。這些提示框和模態(tài)框除了功能相似以外,沒有其他共同點(diǎn):它們看起來不一樣,用法不一樣,但是邏輯一樣。

  1. // 模態(tài)框 
  2.  
  3. const Modal = { 
  4.  
  5.   template: '#modal'
  6.  
  7.   data() { 
  8.  
  9.     return { 
  10.  
  11.       isShowing: false 
  12.  
  13.     } 
  14.  
  15.   }, 
  16.  
  17.   methods: { 
  18.  
  19.     toggleShow() { 
  20.  
  21.       this.isShowing = !this.isShowing; 
  22.  
  23.     } 
  24.  
  25.   }, 
  26.  
  27.   components: { 
  28.  
  29.     appChild: Child 
  30.  
  31.   } 
  32.  
  33.  
  34.   
  35.  
  36. // 提示框 
  37.  
  38. const Tooltip = { 
  39.  
  40.   template: '#tooltip'
  41.  
  42.   data() { 
  43.  
  44.     return { 
  45.  
  46.       isShowing: false 
  47.  
  48.     } 
  49.  
  50.   }, 
  51.  
  52.   methods: { 
  53.  
  54.     toggleShow() { 
  55.  
  56.       this.isShowing = !this.isShowing; 
  57.  
  58.     } 
  59.  
  60.   }, 
  61.  
  62.   components: { 
  63.  
  64.     appChild: Child 
  65.  
  66.   } 
  67.  
  68.  

我們可以在這里提取邏輯并創(chuàng)建可以被重用的項(xiàng):

  1. const toggle = { 
  2.  
  3.   data() { 
  4.  
  5.     return { 
  6.  
  7.       isShowing: false 
  8.  
  9.     } 
  10.  
  11.   }, 
  12.  
  13.   methods: { 
  14.  
  15.     toggleShow() { 
  16.  
  17.       this.isShowing = !this.isShowing; 
  18.  
  19.     } 
  20.  
  21.   } 
  22.  
  23.  
  24.   
  25.  
  26. const Modal = { 
  27.  
  28.   template: '#modal'
  29.  
  30.   mixins: [toggle], 
  31.  
  32.   components: { 
  33.  
  34.     appChild: Child 
  35.  
  36.   } 
  37.  
  38. }; 
  39.  
  40.   
  41.  
  42. const Tooltip = { 
  43.  
  44.   template: '#tooltip'
  45.  
  46.   mixins: [toggle], 
  47.  
  48.   components: { 
  49.  
  50.     appChild: Child 
  51.  
  52.   } 
  53.  
  54. };  

你可以點(diǎn)擊這里,查看 Sarah Drasner(@sdras) 在CodePen上編寫 Mixin 的例子

為了更容易理解Mixin,這個(gè)例子故意編寫得簡單一些。真實(shí)應(yīng)用中Mixin有如下的應(yīng)用,但是它的作用也不僅限于此:獲取視窗和組件的尺寸,采集特定的鼠標(biāo)事件和圖表的基本元素。Paul Pflugradt 有一個(gè)關(guān)于 Vue Mixins 的優(yōu)秀項(xiàng)目,值得一提的是它是用 coffeescript 編寫的。

用法

上面這個(gè)codepen的例子并沒有告訴我們在一個(gè)真實(shí)的應(yīng)用中如何使用Mixin,所以我們看看下面的這個(gè)。

你可以按照你喜歡的任意方式設(shè)置你的目錄結(jié)構(gòu),但為了結(jié)構(gòu)規(guī)整我喜歡新建一個(gè)mixin目錄。我們創(chuàng)建的這個(gè)文件含有.js擴(kuò)展名(跟.vue相對(duì),就像我們的其他文件),為了使用Mixin我們需要輸出一個(gè)對(duì)象。

 

接著我們可以在Modal.vue使用這樣的寫法,來引入這個(gè)Mixin:

  1. import Child from './Child' 
  2.  
  3. import { toggle } from './mixins/toggle' 
  4.  
  5.   
  6.  
  7. export default { 
  8.  
  9.   name'modal'
  10.  
  11.   mixins: [toggle], 
  12.  
  13.   components: { 
  14.  
  15.     appChild: Child 
  16.  
  17.   } 
  18.  
  19.  

即便我們使用的是一個(gè)對(duì)象而不是一個(gè)組件,生命周期函數(shù)對(duì)我們來說仍然是可用的,理解這點(diǎn)很重要。我們也可以這里使用mounted()鉤子函數(shù),它將被應(yīng)用于組件的生命周期上。這種工作方式真的很靈活也很強(qiáng)大。

合并

在下面的這個(gè)例子,我們可以看到,我們不僅僅是實(shí)現(xiàn)了自己想要的功能,并且Mixin中的生命周期的鉤子也同樣是可用的。因此,當(dāng)我們在組件上應(yīng)用Mixin的時(shí)候,有可能組件與Mixin中都定義了相同的生命周期鉤子,這時(shí)候鉤子的執(zhí)行順序的問題凸顯了出來。默認(rèn)Mixin上會(huì)首先被注冊,組件上的接著注冊,這樣我們就可以在組件中按需要重寫Mixin中的語句。組件擁有最終發(fā)言權(quán)。當(dāng)發(fā)生沖突并且這個(gè)組件就不得不“決定”哪個(gè)勝出的時(shí)候,這一點(diǎn)就顯得特別重要,否則,所有的東西都被放在一個(gè)數(shù)組當(dāng)中執(zhí)行,Mixin將要被先推入數(shù)組,其次才是組件。

  1. //mixin 
  2.  
  3. const hi = { 
  4.  
  5.   mounted() { 
  6.  
  7.     console.log('hello from mixin!'
  8.  
  9.   } 
  10.  
  11.  
  12.   
  13.  
  14. //vue instance or component 
  15.  
  16. new Vue({ 
  17.  
  18.   el: '#app'
  19.  
  20.   mixins: [hi], 
  21.  
  22.   mounted() { 
  23.  
  24.     console.log('hello from Vue instance!'
  25.  
  26.   } 
  27.  
  28. }); 
  29.  
  30.   
  31.  
  32. //Output in console 
  33.  
  34. > hello from mixin! 
  35.  
  36. > hello from Vue instance!  

如果這兩個(gè)沖突了,我們看看 Vue實(shí)例或組件是如何決定輸贏的:

  1. //mixin 
  2.  
  3. const hi = { 
  4.  
  5.   methods: { 
  6.  
  7.     sayHello: function() { 
  8.  
  9.       console.log('hello from mixin!'
  10.  
  11.     } 
  12.  
  13.   }, 
  14.  
  15.   mounted() { 
  16.  
  17.     this.sayHello() 
  18.  
  19.   } 
  20.  
  21.  
  22.   
  23.  
  24. //vue instance or component 
  25.  
  26. new Vue({ 
  27.  
  28.   el: '#app'
  29.  
  30.   mixins: [hi], 
  31.  
  32.   methods: { 
  33.  
  34.     sayHello: function() { 
  35.  
  36.       console.log('hello from Vue instance!'
  37.  
  38.     } 
  39.  
  40.   }, 
  41.  
  42.   mounted() { 
  43.  
  44.     this.sayHello() 
  45.  
  46.   } 
  47.  
  48. }) 
  49.  
  50.   
  51.  
  52. // Output in console 
  53.  
  54. > hello from Vue instance! 
  55.  
  56. > hello from Vue instance!  

你可能已經(jīng)注意到這有兩個(gè)console.log而不是一個(gè)——這是因?yàn)?**個(gè)函數(shù)被調(diào)用時(shí),沒有被銷毀,它只是被重寫了。我們在這里調(diào)用了兩次sayHello()函數(shù)。

全局Mixin

當(dāng)我們使用“全局”來描述Mixin的時(shí)候,我們并不是說Mixin能夠像filter,在每個(gè)組件都能被訪問到。只是我們能夠在組件通過mixins:[toggle]訪問組件上的Mixin對(duì)象。

全局Mixin被注冊到了每個(gè)單一組件上。因此,它們的使用場景極其有限并且在使用的時(shí)候我們需要非常小心。一個(gè)我能想到的用途就是類似于插件,你需要賦予它訪問所有東西的權(quán)限。但即使在這種情況下,我也對(duì)你正在做事情的充滿警惕,尤其當(dāng)你打算為應(yīng)用增加通能的時(shí)候,這樣做可能對(duì)你來說是個(gè)潘多拉的盒子。

為了創(chuàng)建一個(gè)全局實(shí)例,我們可以把它放在Vue實(shí)例之上。在一個(gè)典型的 Vue-cli 初始化的項(xiàng)目中,它可能在你的main.js文件中。

  1. Vue.mixin({ 
  2.  
  3.   mounted() { 
  4.  
  5.     console.log('hello from mixin!'
  6.  
  7.   } 
  8.  
  9. }) 
  10.  
  11.   
  12.  
  13. new Vue({ 
  14.  
  15.   ... 
  16.  
  17. })  

再次提醒,小心使用它!那個(gè)console.log將會(huì)出現(xiàn)在每個(gè)組件上,在這個(gè)案例里還不算壞(除了控制臺(tái)上有多余的輸出)。但如果全局Mixin被錯(cuò)誤的使用,你將能看到它有多可怕。

結(jié)論

Mixin對(duì)于封裝一小段想要復(fù)用的代碼來講是有用的。對(duì)你來說Mixin當(dāng)然不是唯一可行的選擇:比如說高階組件就允許你組合相似函數(shù),Mixin只是的一種實(shí)現(xiàn)方式。我喜歡Mixin,因?yàn)槲也恍枰獋鬟f狀態(tài),但是這種模式當(dāng)然也可能會(huì)被濫用,所以,仔細(xì)思考下哪種選擇對(duì)你的應(yīng)用最有意義吧! 

責(zé)任編輯:龐桂玉 來源: 前端大全
相關(guān)推薦

2021-04-17 18:24:04

Vue.js嵌套路由前端

2023-07-28 13:55:40

便捷選項(xiàng)組件

2019-07-26 14:40:58

Vue.jsSocket.IO前端

2021-05-08 06:14:28

Vue.js片段開發(fā)

2018-04-04 10:32:13

前端JavascriptVue.js

2017-07-04 17:55:37

Vue.js插件開發(fā)

2016-11-04 19:58:39

vue.js

2022-01-19 22:18:56

Vue.jsVue SPA開發(fā)

2023-10-19 13:56:00

Vue項(xiàng)目Mock.js

2024-05-13 08:04:26

Vue.jsWeb應(yīng)用程序

2017-07-11 18:00:21

vue.js數(shù)據(jù)組件

2017-07-20 11:18:22

Vue.jsMVVMMVC

2021-01-22 11:47:27

Vue.js響應(yīng)式代碼

2016-11-01 19:10:33

vue.js前端前端框架

2020-09-07 14:40:20

Vue.js構(gòu)建工具前端

2016-09-21 13:32:13

JavascriptWeb前端

2020-09-16 06:12:30

Vue.js 3.0Suspense組件前端

2017-08-30 17:10:43

前端JavascriptVue.js

2024-01-18 11:50:28

2023-03-16 14:29:48

Vue.js測試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)