vue中mixins的理解及應用

vue中提供了一種混合機制--mixins,用來更高效的實現組件內容的複用。最開始我一度認爲這個和組件好像沒啥區別。。後來發現錯了。下面我們來看看mixins和普通情況下引入組件有什麼區別?

mixins

混合 (mixins) 是一種分發 Vue 組件中可複用功能的非常靈活的方式。
混合對象可以包含任意組件選項
當組件使用混合對象時,所有混合對象的選項將被混入該組件本身的選項。

mixins理解

組件在引用之後相當於在父組件內開闢了一塊單獨的空間,來根據父組件props過來的值進行相應的操作,單本質上兩者還是涇渭分明,相對獨立。

而mixins則是在引入組件之後,則是將組件內部的內容如data等方法、method等屬性與父組件相應內容進行合併。相當於在引入後,父組件的各種屬性方法都被擴充了。

  • 單純組件引用:
    父組件 + 子組件 >>> 父組件 + 子組件
  • mixins:
    父組件 + 子組件 >>> new父組件
    有點像註冊了一個vue的公共方法,可以綁定在多個組件或者多個Vue對象實例中使用。另一點,類似於在原型對象中註冊方法,實例對象即組件或者Vue實例對象中,仍然可以定義相同函數名的方法進行覆蓋,有點像子類和父類的感覺。

mixins的使用

方法的複用

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之前,在兩個不同的組件的組件中調用foo方法,需要重複定義,倘若方法比較複雜,代碼將更加冗餘。若藉助mixins,則變得十分簡單:

 

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]
})

雖然此處,兩個組件用可以通過this.msg引用mixins中定義的msg,但是,小編嘗試過,兩個組件引用的並不是同一個msg,而是各自創建了一個新的msg。如果在組件中定義相同的data,則此處會引用組件中的msg,而非mixins中的。

方法的覆蓋

如果在引用mixins的同時,在組件中重複定義相同的方法,則mixins中的方法會被覆蓋。

 

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

此時,若單擊h1標籤,則在控制檯中打印"Child foo() 1" 3、合併生命週期此時,若單擊h1標籤,則在控制檯中打印"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)
        }
    }
})

通過上面的介紹,現在對mixins有了比較深入的瞭解,在設計複雜組件時是很有必要的。

實踐:狀態碼統一過濾

一般情況下不要全局使用,因爲會污染vue所有實例,這裏通過一個簡單的應用展示mixin的使用技巧,在所有vue實例中添加統一狀態碼過濾器。

因爲自定義方法會在所有的實例中混入,如果按照以前的方法,難免會有覆蓋原先的方法的危險,按照官方的建議,混入的自定義方法名增加前綴 $_ 用作區分。

創建一個 config.js 文件,用於保存狀態碼對應的含義,將其暴露出去

 

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

再創建一個 filters.js 文件,用於保存所有的自定義函數

 

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

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

 

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

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

 

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

包裝插件

接下來簡單應用一下 Vue 中插件的製作方法。創建插件之後,就可以 Vue.use(myPlugin) 來使用了。

首先附上插件的 官方文檔[點我查看]

一句話解釋,包裝的插件需要一個 install 的方法將插件裝載到 Vue 上。

關於 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
  };
}

很直觀的就看到他在最後調用了 plugin.install 的方法,我們要做的就是處理好這個 install 函數即可。

config.js 文件依舊需要,這裏保存了所有狀態碼對應的轉義文字

創建一個 myPlugin.js 文件,這個就是我們編寫的插件

 

import { typeConfig } from "./config"

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

插件的 install 函數的第一個參數爲 Vue 的實例,後面還可以傳入一些自定義參數。

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

 

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

至此,我們已經完成了一個小小的插件,並將我們的狀態碼轉義過濾器放入了所有的 Vue 實例中,在 .vue 的模板文件中,我們可以使用 {{ typeStatus | $_filterType }} 來進行狀態碼轉義了。

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



作者:老鼠AI大米_Java全棧
鏈接:https://www.jianshu.com/p/a72bf060eeaa
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章