Vue — 詳解mixins混入使用域醇,應(yīng)用場(chǎng)景

混入是vue官方文檔提出的 關(guān)于vue復(fù)用性的一種方式吹散,看了文檔似懂弧械,查找了下網(wǎng)上的講解,整理下好好縷一縷這個(gè)東西

前言

當(dāng)我們的項(xiàng)目越來(lái)越大空民,我們會(huì)發(fā)現(xiàn)組件之間可能存在很多相似的功能刃唐,你在一遍又一遍的復(fù)制粘貼相同的代碼段(data,method界轩,watch画饥、mounted等),如果我們?cè)诿總€(gè)組件中去重復(fù)定義這些屬性和方法會(huì)使得項(xiàng)目出現(xiàn)代碼冗余并提高了維護(hù)難度浊猾,針對(duì)這種情況官方提供了Mixins特性

一抖甘、什么是Mixins? mixins是一個(gè)js對(duì)象

混入 (mixin) 提供了一種非常靈活的方式与殃,來(lái)分發(fā) Vue 組件中的可復(fù)用功能单山。一個(gè)混入對(duì)象可以包含任意組件選項(xiàng)。當(dāng)組件使用混入對(duì)象時(shí)幅疼,所有混入對(duì)象的選項(xiàng)將被“混合”進(jìn)入該組件本身的選項(xiàng)。

mixins(混入)昼接,官方的描述是一種分發(fā) Vue 組件中可復(fù)用功能的非常靈活的方式爽篷,mixins是一個(gè)js對(duì)象,它可以包含我們組件中script項(xiàng)中的任意功能選項(xiàng)慢睡,如data逐工、components、methods 漂辐、created泪喊、computed等等。

我們只要將共用的功能以對(duì)象的方式傳入 mixins選項(xiàng)中髓涯,當(dāng)組件引用 mixins對(duì)象時(shí)所有mixins對(duì)象的選項(xiàng)都將被混入該組件本身的選項(xiàng)中來(lái)袒啼,這樣就可以提高代碼的重用性,使你的代碼保持干凈和易于維護(hù)。

image.png

放大看這張圖:右邊就是一個(gè)混入對(duì)象; 左邊引用了混入對(duì)象

二蚓再、什么時(shí)候使用Mixins滑肉?

當(dāng)我們存在多個(gè)組件中的數(shù)據(jù)或者功能很相近時(shí),我們就可以利用mixins將公共部分提取出來(lái)摘仅,通過(guò) mixins封裝的函數(shù)靶庙,組件調(diào)用他們是不會(huì)改變函數(shù)作用域外部的。
作用: 減少data娃属、methods六荒、鉤子的重復(fù)
????????
文章最后會(huì)舉例應(yīng)用場(chǎng)景~

三、如何創(chuàng)建Mixins矾端?

在src目錄下創(chuàng)建一個(gè)mixins文件夾掏击,文件夾下新建一個(gè)myMixins.js文件。前面我們說(shuō)了mixins是一個(gè)js對(duì)象须床,所以應(yīng)該以對(duì)象的形式來(lái)定義myMixins铐料,在對(duì)象中我們可以和vue組件一樣來(lái)定義我們的data、components豺旬、methods 钠惩、created、computed等屬性族阅,并通過(guò)export導(dǎo)出該對(duì)象


image.png

四篓跛、如何使用Mixins?

前面在myMixins.js中輸出一個(gè)混入對(duì)象坦刀,然后在需要調(diào)用的組件中引入myMixins.js文件即可


image.png

五愧沟、Mixins的特點(diǎn)

特點(diǎn)1:方法和參數(shù)在各組件中不共享,雖然組件調(diào)用了mixins并將其屬性合并到自身組件中來(lái)了鲤遥,但是其屬性只會(huì)被當(dāng)前組件所識(shí)別并不會(huì)被共享沐寺。

??也就是當(dāng)前組件對(duì)mixins的屬性的修改,其他也引用了這個(gè)mixins的組件并不會(huì)受影響盖奈。??

① 首先我們?cè)诨旌蠈?duì)象myMixins.js中定義一個(gè)age字段和getAge方法

export const myMixins = {
  components:{},
  data() {
    return {
      age: 18,
    }
  },
  mounted() {
    this.getAge()
  },
  methods: {
    getAge() {
      console.log(this.age)
    }
  }
}

② 此時(shí)組件1引用了這個(gè)mixins混坞,組件1中對(duì)num進(jìn)行+1操作

// 這是組件1
import { myMixins } from "@/mixins/myMixins.js";
export default {
  mixins: [myMixins],
  data() {
    return {}
  },
  created() {
    this.age++   // 組件1的age變成了19啦
  },
}

③ 組件2不進(jìn)行操作

export default {
  mixins: [myMixins],
  data() {
    return {}
  },
}

④ 我們分別切換到兩個(gè)頁(yè)面,查看控制臺(tái)輸出钢坦。會(huì)發(fā)現(xiàn)組件1改變了age里面的值究孕,組件2中age值還是混合對(duì)象的初始值,并沒(méi)有隨著組件1的增加而改變


image.png

特點(diǎn)2:引入mixins后爹凹,組件會(huì)對(duì)其進(jìn)行合并厨诸,將mixins中的數(shù)據(jù)和方法拓展到當(dāng)前組件中來(lái),如果當(dāng)前組件也有同名稱的屬性或者方法禾酱,在合并的過(guò)程中會(huì)出現(xiàn)沖突微酬,接下來(lái)我們?cè)敿?xì)了解Mixins合并沖突

六绘趋、Mixins合并沖突

【6.1】混入對(duì)象里的(components、methods 、computed、data)這些選項(xiàng)瘦棋,混入組件時(shí)選項(xiàng)會(huì)被合并扮休,重名沖突時(shí)優(yōu)先采用組件的 ??,組件中的鍵會(huì)覆蓋混入對(duì)象的

① 我們?cè)诨烊雽?duì)象增加age屬性、getAge1方法和getAge2方法

// myMixins.js
export const myMixins = {
  components:{},
  data() {
    return {
      age: 18,
    }
  },
  methods: {
    getAge1() {
      console.log("age1 from mixins =", this.age )
    },
    getAge2() {
      console.log("age2 from mixins =", this.age )
    },
  }
}

② 我們?cè)谝肓薽yMixins文件的組件中,增加age屬性、getAge1方法和getAge3方法

// template.vue
import { myMixins } from "@/mixins/myMixins.js";
export default {
  mixins: [myMixins],
  data() {
    return {
      age: 20,
    }
  },
  mounted() {
    this.getAge1();
    this.getAge2();
    this.getAge3();
  },
  methods: {
    getAge1() {
      console.log('age1 from template =', this.age)
    },
    getAge3() {
      console.log('age3 from template =', this.age)
    },
  }
}

③ 我們會(huì)發(fā)現(xiàn):
組件中的age覆蓋了混合對(duì)象的age茬斧,
組件的getAge1方法覆蓋了混合對(duì)象的getAge1方法


image.png

【6.2】值為函數(shù)(created、mounted)的選項(xiàng)梗逮,混入組件時(shí)選項(xiàng)會(huì)被合并調(diào)用项秉,
?? 混合對(duì)象里的鉤子函數(shù)在組件里的鉤子函數(shù)之前調(diào)用

// myMixins.js
export const myMixins = {
  components:{},
  data() {
    return {}
  },
  created() {
    console.log('xxx from mixins')
  }
}

再看看引用了mixins的組件

import { myMixins } from "@/mixins/myMixins.js";
export default {
  mixins: [myMixins],
  data() {
    return {}
  },
  created() {
    console.log('xxx from template')
  }
}

結(jié)果 mixins自己的created 比 引用了mixins的組件里的created先執(zhí)行


image.png

七、全局混入

嚴(yán)重警告:一旦使用全局混入慷彤,它將影響每一個(gè)之后創(chuàng)建的 Vue 實(shí)例娄蔼。
使用恰當(dāng)時(shí),這可以用來(lái)為自定義選項(xiàng)注入處理邏輯底哗。

// 為自定義的選項(xiàng) 'myOption' 注入一個(gè)處理器岁诉。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

new Vue({
  myOption: 'hello!'
})
// => "hello!"

不建議使用全局混入,全局注冊(cè)之后會(huì)對(duì)所有組件都生效跋选,影響比較大涕癣,項(xiàng)目大的情況下,建議使用局部注冊(cè)

八前标、同時(shí)引入多個(gè)mixin對(duì)象

同時(shí)引入多個(gè) mixins: [mixinsTest2,mixinsTest]

在使用局部注冊(cè)的時(shí)候坠韩,可同時(shí)引入多個(gè)混入對(duì)象,執(zhí)行順序和引入順序一致炼列,此處便不再贅述了只搁。

結(jié)論: 引入多個(gè)以后,,我們先引入的先被使用俭尖,先引用须蜗,先使用!

九目溉、與vuex的區(qū)別

vuex:用來(lái)做狀態(tài)管理的,里面定義的變量在每個(gè)組件中均可以使用和修改菱农,在任一組件中修改此變量的值之后缭付,其他組件中此變量的值也會(huì)隨之修改。

Mixins:可以定義共用的變量循未,在每個(gè)組件中使用陷猫,引入組件中之后秫舌,各個(gè)變量是相互獨(dú)立的,值的修改在組件中不會(huì)相互影響绣檬。

十足陨、與公共組件的區(qū)別

組件:在父組件中引入組件,相當(dāng)于在父組件中給出一片獨(dú)立的空間供子組件使用娇未,然后根據(jù)props來(lái)傳值墨缘,但本質(zhì)上兩者是相對(duì)獨(dú)立的。

Mixins:則是在引入Mixins之后零抬,Mixins與組件中的屬性和方法進(jìn)行合并镊讼,相當(dāng)于擴(kuò)展了父組件的對(duì)象與方法,可以理解為形成了一個(gè)新的組件平夜。

????

另外蝶棋,vue不建議,子組件直接修改props接收到的父組件的數(shù)據(jù)忽妒,但是玩裙,混入可以做到組件的屬性或者方法覆蓋混入對(duì)象的


混入的應(yīng)用場(chǎng)景

假設(shè)我們需要在每個(gè)組件上添加name和time。在created段直、destroyed時(shí),打出提示吃溅,并給出存活時(shí)間。

一共有五個(gè)組件坷牛,請(qǐng)問(wèn)怎么做罕偎?
做法1:給每個(gè)組件添加data和created, destroyed鉤子,重復(fù)5次
做法2:使用mixin減少重復(fù)京闰。

做法1:

<template>
    <div>child1</div>
</template>
<script>
    export default{
        data(){
            return {
                name:'child1',
                time_birth:undefined,
                time_dead:undefined
            }
        },
        created(){
            this.time_birth=new Date();
            console.log(this.name+'出生了');
        },
        beforeDestroy(){
            this.time_dead=new Date();
            console.log(`${this.name}死了颜及,共存活了${this.time_dead-this.time_birth}ms`);
        }
    }
</script>

// 依次對(duì)組件2 3 4 5 分別執(zhí)行這些操作。蹂楣。俏站。

做法1小結(jié): 代碼重復(fù)太多,基本上每個(gè)組件都在復(fù)刻第一個(gè)組件的樣式痊土,這樣下來(lái)肄扎,代碼的維護(hù)性是十分低的。萬(wàn)一有一天要改需求了怎么辦赁酝?又倒回去重新修改5次嗎犯祠?5次并不是真正的5次,萬(wàn)一是10次酌呆,100次呢衡载?很顯然,這種做法并不可取隙袁。接下來(lái)來(lái)看另外一種做法痰娱。

做法2:
創(chuàng)建混入對(duì)象:

const myMixin = {
    data(){
            return {
                /* 每個(gè)組件的名字不同弃榨,用另外的方法賦值。即每個(gè)組件自己帶上自己的名字即可梨睁。 */
                name:undefined,
                time_birth:undefined,
                time_dead:undefined
            }
        },
        created(){
            if(!this.name){
                throw new Error('need name');  // 名字是用的組件里data的name
            }
            this.time_birth=new Date();
            console.log(this.name+'出生了');
        },
        beforeDestroy(){
            this.time_dead=new Date();
            console.log(`${this.name}死了鲸睛,共存活了${this.time_dead-this.time_birth}ms`);
        }
}
export default myMixin;

組件里

<template>
    <div>child1</div>
</template>
<script>
    /* 首先導(dǎo)入公共部分的js內(nèi)容 */
    import myMixin from './Mixins/public.js';
    export default{
        data(){
            return {
                /* 其他組件就寫(xiě)自己組件的名字即可 */
                name:'child1',
            }
        },
        /* 使用導(dǎo)入的public模塊 */
        mixins:[myMixin],
    }
</script>

用了混入后,組件只需要引用混入對(duì)象坡贺,然后在data里填寫(xiě)組件的名字官辈,再掛載一下混入對(duì)象,就好了拴念。

今天就聊到這里钧萍,后續(xù)有想到栗子再補(bǔ)充吧 ??
??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市政鼠,隨后出現(xiàn)的幾起案子风瘦,更是在濱河造成了極大的恐慌,老刑警劉巖公般,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件万搔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡官帘,警方通過(guò)查閱死者的電腦和手機(jī)瞬雹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)刽虹,“玉大人酗捌,你說(shuō)我怎么就攤上這事∮空埽” “怎么了胖缤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)阀圾。 經(jīng)常有香客問(wèn)我哪廓,道長(zhǎng),這世上最難降的妖魔是什么初烘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任涡真,我火速辦了婚禮,結(jié)果婚禮上肾筐,老公的妹妹穿的比我還像新娘哆料。我一直安慰自己,他們只是感情好吗铐,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布剧劝。 她就那樣靜靜地躺著,像睡著了一般抓歼。 火紅的嫁衣襯著肌膚如雪讥此。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天谣妻,我揣著相機(jī)與錄音萄喳,去河邊找鬼。 笑死蹋半,一個(gè)胖子當(dāng)著我的面吹牛他巨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播减江,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼染突,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了辈灼?” 一聲冷哼從身側(cè)響起份企,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巡莹,沒(méi)想到半個(gè)月后司志,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡降宅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年骂远,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腰根。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡激才,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出额嘿,到底是詐尸還是另有隱情瘸恼,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布岩睁,位于F島的核電站钞脂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏捕儒。R本人自食惡果不足惜冰啃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刘莹。 院中可真熱鬧阎毅,春花似錦、人聲如沸点弯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抢肛。三九已至狼钮,卻和暖如春碳柱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背熬芜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工莲镣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涎拉。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓瑞侮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鼓拧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子半火,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容