vue中mixins的理解及應(yīng)用

vue中提供了一種混合機(jī)制--mixins,用來(lái)更高效的實(shí)現(xiàn)組件內(nèi)容的復(fù)用。最開(kāi)始我一度認(rèn)為這個(gè)和組件好像沒(méi)啥區(qū)別。。后來(lái)發(fā)現(xiàn)錯(cuò)了。下面我們來(lái)看看mixins和普通情況下引入組件有什么區(qū)別?

mixins

混合 (mixins) 是一種分發(fā) Vue 組件中可復(fù)用功能的非常靈活的方式。
混合對(duì)象可以包含任意組件選項(xiàng)
當(dāng)組件使用混合對(duì)象時(shí),所有混合對(duì)象的選項(xiàng)將被混入該組件本身的選項(xiàng)。

mixins理解

組件在引用之后相當(dāng)于在父組件內(nèi)開(kāi)辟了一塊單獨(dú)的空間,來(lái)根據(jù)父組件props過(guò)來(lái)的值進(jìn)行相應(yīng)的操作,單本質(zhì)上兩者還是涇渭分明,相對(duì)獨(dú)立。

而mixins則是在引入組件之后,則是將組件內(nèi)部的內(nèi)容如data等方法、method等屬性與父組件相應(yīng)內(nèi)容進(jìn)行合并。相當(dāng)于在引入后,父組件的各種屬性方法都被擴(kuò)充了。

  • 單純組件引用:
    父組件 + 子組件 >>> 父組件 + 子組件
  • mixins:
    父組件 + 子組件 >>> new父組件
    有點(diǎn)像注冊(cè)了一個(gè)vue的公共方法,可以綁定在多個(gè)組件或者多個(gè)Vue對(duì)象實(shí)例中使用。另一點(diǎn),類(lèi)似于在原型對(duì)象中注冊(cè)方法,實(shí)例對(duì)象即組件或者Vue實(shí)例對(duì)象中,仍然可以定義相同函數(shù)名的方法進(jìn)行覆蓋,有點(diǎn)像子類(lèi)和父類(lèi)的感覺(jué)。

mixins的使用

方法的復(fù)用

html

<div id="app">
    <child></child>
    <kid></kid>
</div>

js

Vue.component('child',{
    template:`<h1 @click="foo">child component</h1>`,
    methods:{
        foo(){
            console.log('Child foo()'+this.msg++)
        }
    }
})
 
Vue.component('kid',{
    template:`<h1 @click="foo">kid component</h1>`,
    methods:{
        foo(){
            console.log('Kid foo()'+this.msg++)
        }
    }
})

在借助mixins之前,在兩個(gè)不同的組件的組件中調(diào)用foo方法,需要重復(fù)定義,倘若方法比較復(fù)雜,代碼將更加冗余。若借助mixins,則變得十分簡(jiǎn)單:

let mixin={
    data(){
        return{
            msg:1
        }
    },
    methods:{
        foo(){
            console.log('hello from mixin!----'+this.msg++)
        }
    }
}
var child=Vue.component('child',{ 
        template:`<h1 @click="foo">child component</h1>`, 
        mixins:[mixin]
})
Vue.component('kid',{ 
        template:`<h1 @click="foo">kid component</h1>`, 
        mixins:[mixin]
})

雖然此處,兩個(gè)組件用可以通過(guò)this.msg引用mixins中定義的msg,但是,小編嘗試過(guò),兩個(gè)組件引用的并不是同一個(gè)msg,而是各自創(chuàng)建了一個(gè)新的msg。如果在組件中定義相同的data,則此處會(huì)引用組件中的msg,而非mixins中的。

方法的覆蓋

如果在引用mixins的同時(shí),在組件中重復(fù)定義相同的方法,則mixins中的方法會(huì)被覆蓋。

var child=Vue.component('child',{
    template:`<h1 @click="foo">child component</h1>`,
    mixins:[mixin],
    methods:{
        foo(){
            console.log('Child foo()'+this.msg++)
        }
    }
})

此時(shí),若單擊h1標(biāo)簽,則在控制臺(tái)中打印"Child foo() 1" 3、合并生命周期此時(shí),若單擊h1標(biāo)簽,則在控制臺(tái)中打印"Child foo() 1"

合并生命周期

let mixin={
    mounted(){
        console.log('mixin say hi')//先輸出
    },
    data(){
        return{
            msg:1
        }
    },
    methods:{
        foo(){
            console.log('mixin foo()'+this.msg++)
        }
    }
}
let vm=new Vue({
    el:"#app",
    data:{
        msg: 2
    },
    mounted: function(){
        console.log('app say hi')//后輸出
    },
    methods:{
        foo(){
            console.log('Parent foo()'+this.msg)
        }
    }
})

通過(guò)上面的介紹,現(xiàn)在對(duì)mixins有了比較深入的了解,在設(shè)計(jì)復(fù)雜組件時(shí)是很有必要的。

實(shí)踐:狀態(tài)碼統(tǒng)一過(guò)濾

一般情況下不要全局使用,因?yàn)闀?huì)污染vue所有實(shí)例,這里通過(guò)一個(gè)簡(jiǎn)單的應(yīng)用展示mixin的使用技巧,在所有vue實(shí)例中添加統(tǒng)一狀態(tài)碼過(guò)濾器。

因?yàn)樽远x方法會(huì)在所有的實(shí)例中混入,如果按照以前的方法,難免會(huì)有覆蓋原先的方法的危險(xiǎn),按照官方的建議,混入的自定義方法名增加前綴 $_ 用作區(qū)分。

創(chuàng)建一個(gè) config.js 文件,用于保存狀態(tài)碼對(duì)應(yīng)的含義,將其暴露出去

export const typeConfig = {
  1: "type one",
  2: "type two",
  3: "type three"
}

再創(chuàng)建一個(gè) filters.js 文件,用于保存所有的自定義函數(shù)

import { typeConfig } from "./config"
export default {
  filters: {
    $_filterType: (value) => {
      return typeConfig[value] || "type undefined"
    }
  }
}

最后,在 main.js 中引入我們的 filters 方法集

import filter from "./filters"
Vue.mixin(filter)

接下來(lái),我們就可以在 .vue 的模板文件中隨意使用自定義函數(shù)了

<template>
  <div>{{typeStatus | $_filterType}}<div>
</template>

包裝插件

接下來(lái)簡(jiǎn)單應(yīng)用一下 Vue 中插件的制作方法。創(chuàng)建插件之后,就可以 Vue.use(myPlugin) 來(lái)使用了。

首先附上插件的 官方文檔[點(diǎn)我查看]

一句話解釋?zhuān)b的插件需要一個(gè) install 的方法將插件裝載到 Vue 上。

關(guān)于 Vue.use() 的源碼

function initUse (Vue) {
  Vue.use = function (plugin) {
    var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    var args = toArray(arguments, 1);
    args.unshift(this);
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args);
    }
    installedPlugins.push(plugin);
    return this
  };
}

很直觀的就看到他在最后調(diào)用了 plugin.install 的方法,我們要做的就是處理好這個(gè) install 函數(shù)即可。

config.js 文件依舊需要,這里保存了所有狀態(tài)碼對(duì)應(yīng)的轉(zhuǎn)義文字

創(chuàng)建一個(gè) myPlugin.js 文件,這個(gè)就是我們編寫(xiě)的插件

import { typeConfig } from "./config"

myPlugin.install = (Vue) => {
  Vue.mixin({
    filters: {
      $_filterType: (value) => {
        return typeConfig[value] || "type undefined"
      }
    }
  })
}
export default myPlugin

插件的 install 函數(shù)的第一個(gè)參數(shù)為 Vue 的實(shí)例,后面還可以傳入一些自定義參數(shù)。

在 main.js 文件中,我們不用 Vue.mixin() 轉(zhuǎn)而使用 Vue.use() 來(lái)完成插件的裝載。

import myPlugin from "./myPlugin"
Vue.use(myPlugin)

至此,我們已經(jīng)完成了一個(gè)小小的插件,并將我們的狀態(tài)碼轉(zhuǎn)義過(guò)濾器放入了所有的 Vue 實(shí)例中,在 .vue 的模板文件中,我們可以使用 {{ typeStatus | $_filterType }} 來(lái)進(jìn)行狀態(tài)碼轉(zhuǎn)義了。

Vue.mixin() 可以將自定義的方法混入所有的 Vue 實(shí)例中,謹(jǐn)慎使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容