您好,登錄后才能下訂單哦!
這篇文章主要介紹“vuejs中怎么使用mixin局部混入與全局混入”,在日常操作中,相信很多人在vuejs中怎么使用mixin局部混入與全局混入問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”vuejs中怎么使用mixin局部混入與全局混入”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
假設(shè):現(xiàn)在有兩個不同的按鈕組件ButtonA,ButtonB,點擊它彈出組件自身不同的屬性
用Vue-cli腳手架創(chuàng)建一個項目,在components文件夾下分別創(chuàng)建ButtonA.vue,ButtonB.vue兩個組件
以下是ButtonA組件內(nèi)容,在按鈕上綁定了handleButton方法,并在methods選項配置中定義
<template> <div class="wrap"> <button @click="handleButton">按鈕組件A</button> </div> </template> <script> export default { name: "ButtonA", data() { return { name: "itclan.cn" } }, methods: { handleButton() { alert(this.name); } } } </script> <style lang="scss" scoped> .wrap { margin-right: 20px; } </style>
以下是ButtonB組件內(nèi)容,在按鈕上綁定了handleButton方法,并在methods選項配置中定義
<template> <div> <button @click="handleButton">按鈕組件B</button> </div> </template> <script> export default { name: "ButtonB", data() { return { name: "video.itclan.cn" } }, methods: { handleButton() { alert(this.name); } } } </script> <style lang="scss" scoped> </style>
然后再App.vue當(dāng)中引入兩個ButtonA,ButtonB組件
<template> <div id="app"> <ButtonA></ButtonA> <ButtonB></ButtonB> </div> </template> <script> import ButtonA from "./components/ButtonA" import ButtonB from "./components/ButtonB" export default { name: 'App', components: { ButtonA, ButtonB } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; display: flex; justify-content: center; } </style>
經(jīng)過上面的幾行代碼,可以實現(xiàn)我們想要的目的,但是你會發(fā)現(xiàn),他們的功能邏輯都是一樣的,定義的方法名也都是一樣的
如果一個項目里,有很多個這樣的組件,只要想改,那么所有的單文件組件都得手動的修改一次,毫無疑問,重復(fù)性的代碼也比較多,比較分散
對于不同組件間同樣的配置,能不能提取出來共用一份呢,在Vue當(dāng)中,提供了mixin
把多個組件共有的配置提取成一個混入對象,然后通過局部混入或者全局混入,以達到共用配置的目的,這就是mixin
官方文檔: 混入 (mixin) 提供了一種非常靈活的方式,來分發(fā) Vue 組件中的可復(fù)用功能。一個混入對象可以包含任意組件選項。當(dāng)組件使用混入對象時,所有混入對象的選項將被“混合”進入該組件本身的選項
翻譯一下: 將組件的公共邏輯或者配置(包括data,方法,生命周期,甚至props等)提取出來,哪個組件需要用到時,直接將提取的這部分混入到組件內(nèi)部即可。這樣既可以減少代碼冗余度,也可以讓后期維護起來更加容易,改一處即可,不用到處去每個組件內(nèi)修改配置
注意:提取的是邏輯或配置,而不是HTML代碼和CSS代碼。也就是說,mixin就是組件中的組件,Vue組件化讓我們的代碼復(fù)用性更高
那么組件與組件之間還有重復(fù)部分,比如邏輯業(yè)務(wù)的復(fù)用,我們還可以使用Mixin在抽離一遍
以下是經(jīng)過mixin改寫過的
在src文件夾下創(chuàng)建一個mixin文件夾(這個文件夾下全部放入一些混入),創(chuàng)建一個popButton.js文件,創(chuàng)建一個對象,然后暴露出去,如下所示
export const popButton = { // 這里面組件選項的配置都是可以的,生命周期等,data屬性,計算屬性,監(jiān)聽屬性等 methods: { handleButton() { alert(this.name); } } }
然后再組件使用處引入即可,如下ButtonA組件,通過import引入,同時在組件配置選項中mixins:[引入的混入名],要是多個的話,用逗號分隔
<template> <div class="wrap"> <button @click="handleButton">按鈕組件A</button> </div> </template> <script> import {popButton} from "../mixin/popButton.js" export default { name: "ButtonA", mixins: [popButton], data() { return { name: "itclan.cn" } }, } </script> <style lang="scss" scoped> .wrap { margin-right: 20px; } </style>
這種在組件內(nèi)部,通過minxins:[混入名稱],也被視為局部混入
局部混入也就是只在當(dāng)前組件內(nèi)起作用,與按需加載有些相似,也就是需要用到mixin中的代碼時,我們再在組件內(nèi)引入它
而全局混入的話,則代表我在項目的任何組件中都可以使用mixin,從根組件下至到它的任何一個組件都會用到混入
局部混入是,在需要的組件引入混入,通過import導(dǎo)入混入,在通過在組件的配置選項中通過minxins: [混入名稱]
而全局混入,則是在項目代碼中的main.js中去引入混入,在用Vue.mixin(混入名稱)進行注冊
這樣任何一個組件,都可以使用混入了的,如下代碼所示
import Vue from 'vue' import App from './App.vue' import {popButton} from "./mixin/popButton.js" Vue.mixin(popButton); Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')
::: tip 注意事項 在使用全局混入時,應(yīng)當(dāng)格外小心,一旦使用全局混入,它將影響每一個之后創(chuàng)建的vue實例,也就是所有的vm,vc都會有混入
它與局部混入沒有啥區(qū)別,雖然一次性注入混入很方便,但是也會帶來一些問題,所有的組件實例,Vue實例都會有混入
在官方的特殊提示里,提到了,謹慎使用全局混入,因為它會影響每個單獨創(chuàng)建的vue實例(包括第三方組件)
大多數(shù)情況下,只應(yīng)當(dāng)應(yīng)用于自定義選項,就像上面示例一樣,推薦將其作為插件發(fā)布,以避免重復(fù)應(yīng)用混入 :::
mixin中的生命周期函數(shù)會和組件的生命周期一起合并執(zhí)行
mixin中的data數(shù)據(jù)在組件中可以使用
mixin中的方法在組件內(nèi)部可以直接調(diào)用
生命周期函數(shù)合并后執(zhí)行順序:先執(zhí)行mixin中的,然后執(zhí)行組件的
mounted不會合并,都會加載一遍
不同組件中的mixin是相互獨立的,改變一個組件中mixin中的數(shù)據(jù),另一個引用了mixin的組件不會受影響
如下代碼
export const popButton = { data() { return { name: "川川", age: 18 } }, created() { console.log("混入生命周期開始執(zhí)行"); }, mounted() { console.log("我是混入"); }, methods: { handleButton() { alert(this.name); }, handleMounted() { console.log("加載方法"); } } }
當(dāng)組件和混入對象含有同名選項時,這些選項將以合適的方式進行合并
也就是說,當(dāng)mixin中定義的數(shù)據(jù),方法名與組件里的屬性名,方法名同名時,會怎么樣呢
會存在數(shù)據(jù),和方法名的覆蓋問題?誰覆蓋誰?執(zhí)行先后順序是?
mixin里面可以有自己的生命周期函數(shù),同組件一樣,生命周期函數(shù)是自執(zhí)行函數(shù),在某個階段會自動執(zhí)行
它都是固定的,默認合并策略如下所示
先執(zhí)行mixin中生命周期函數(shù)中的代碼,然后再執(zhí)行組件內(nèi)部的代碼
export const popButton = { data() { return { name: "川川", age: 18 } }, beforeCreate() { console.log("創(chuàng)建之前"); }, created() { console.log("混入生命周期開始執(zhí)行"); }, mounted() { console.log("我是混入"); }, beforeUpdate() { console.log("更新之前"); }, updated() { console.log("更新之時"); }, beforeDestroy() { console.log("銷毀之前"); }, destroyed() { console.log("銷毀時"); }, methods: { handleButton() { alert(this.name); }, handleMounted() { console.log("加載方法"); } } }
若是方法重名,則后者組件內(nèi)的方法會覆蓋mixin中的方法
當(dāng)mixin中的data數(shù)據(jù)與組件中的data數(shù)據(jù)沖突時,組件中的data數(shù)據(jù)會覆蓋mixin中的數(shù)據(jù)
若是沒有相同的話,會進行數(shù)據(jù)的合并
export const popButton = { data() { return { name: "川川", age: 18 } }, }
在同一個項目里,起相同的名稱,是很容易遇到的,如果mixin中的方法名與引入mixin中組件的方法名一致時,那么以當(dāng)前組件為準(zhǔn)
既然mixin這么好用,那為什么不直接大量推薦使用?mixin可以復(fù)用組件的邏輯,這樣可以節(jié)省很多代碼,但是同樣,也會帶來一些問題
在某些單文件組件里,引入mixin,因為組件內(nèi)可以調(diào)用mixin的方法和使用mixin中定義的數(shù)據(jù),找上下文的時候,變得不是那么直觀,要么通過閱讀代碼逐級向上進行查找,要么就是全局進行搜索查找
使用mixin時,不利于閱讀,代碼變得難以維護
因為組件里可以引入多個mixin,并直接隱式的調(diào)用mixin里面的變量和方法,這會讓寫代碼的人看著有些混亂,區(qū)分不出這些變量和方法,分別是哪個mixin的
所以這里建議是:但凡mixin的方法,統(tǒng)一放到mixin文件夾下進行管理的
當(dāng)遇到組件中定義的屬性,方法與minxin當(dāng)中的出現(xiàn)相同時,后者組件的屬性會覆蓋mixin中的屬性
一個組件可以引用多個mixins一個mixins也可以被多個組件引用,因為是共用邏輯,所以在關(guān)系上,不是很明確
不好追溯代碼,排查問題,可以利用工具vscode全局搜索,如果是很多個地方用到了的mixin那么就得挨個的檢查
如果濫用mixin的話,會讓代碼變得難以維護
如果是用了全局混入,在審查代碼時,在任何一組件當(dāng)中會莫名的多出一些屬性和方法,會令新的同學(xué)很困惑,如果對mixin很熟悉的話,那沒什么,如果不熟悉
那么就非常苦惱,這個變量名和方法,我在組件當(dāng)中明明沒有定義,但是為啥能使用呢,帶來一些困惑
注意
如果一個功能,邏輯,一開始就很確定,它以后是不會動的,那么就可以使用mixin
提高組件代碼復(fù)用性
無需傳遞狀態(tài)
維護方便,只需要修改一處地方就可以,全局混入,應(yīng)當(dāng)謹慎使用
到此,關(guān)于“vuejs中怎么使用mixin局部混入與全局混入”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。