混入是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ù)。
放大看這張圖:右邊就是一個(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ì)象
四篓跛、如何使用Mixins?
前面在myMixins.js中輸出一個(gè)混入對(duì)象坦刀,然后在需要調(diào)用的組件中引入myMixins.js文件即可
五愧沟、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的增加而改變
特點(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方法
【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í)行
七、全局混入
嚴(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ǔ)充吧 ??
??