iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

0
自我挑戰組

跟 VueJS 認識的30天系列 第 18

[DAY18]跟 Vue.js 認識的30天 - Vue 混入(`mixin`)

混入(mixin)似乎也是個初學 Vue 比較少被用到的功能,但還是照順序的了解一下。

基礎運用

在模組中如果有重複出現的模組 option 內容,就可以透過 mixin 將其獨立,並匯入到會使用到該內容的模組裡。

透過創建一個新變數A將重複出現的模組 option 內容集結起來後,再用 mixins:[變數名A] 將資料匯入到模組中。

<component-a></component-a>
<p>根模組 mixinData :{{mixinData}}</p><!--根模組 mixinData :我是被匯入(mixin)的資料-->
<p>根模組 mixinNum :{{mixinNum}}</p><!--根模組 mixinNum :10-->
<p>根模組 computedNum :{{computedNum}}</p><!--根模組 computedNum :11-->

<script>
const Mymixin = {
  created() {
    this.mixinData = "我是被匯入(mixin)的資料";
  },
  computed: {
    computedNum() {
      return this.mixinNum+1;
    }
  }
};
Vue.component("component-a", {
  mixins: [Mymixin],
  template: `<div>
    <p>模組內 mixinData :{{mixinData}}</p><!--模組內 mixinData :我是被匯入(mixin)的資料-->
    <p>模組內 mixinNum :{{mixinNum}}</p><!--模組內 mixinNum :0-->
    <p>模組內 computedNum :{{computedNum}}</p><!--模組內 mixinNum :0-->
  </div>`,
  data() {
    return {
      mixinData: "",
      mixinNum: 0
    };
  }
});

const vm = new Vue({
  el: "#vm",
  mixins: [Mymixin],
  data: {
    mixinData: "",
    mixinNum: 10
  }
});
</script>

發生衝突時的選項合併

以下是在匯入的資料跟模組發生衝突時,Vue 本身對衝突的解決方法。
假設匯入資料跟模組資料具有相同的數據資料

數據資料

<component-a></component-a>
<p>根模組 mixinNum :{{mixinNum}}</p>
<p>根模組 computedNum :{{computedNum}}</p>
<button @click="conflicting">試試重複的methods,打開console</button>
<script>
const Mymixin = {
   data() {
    return {
      mixinData: "我是mixin內的資料",
      mixinNum: 50
    };
  },
  computed: {
    computedNum() {
      console.log("我是被匯入(mixin)的computedNum資料");
      return this.mixinNum + 1;
    }
  },
  methods: {
    conflicting() {
      console.log("from mixin");
    }
  }
};
Vue.component("component-a", {
  mixins: [Mymixin],
  template: `<div>
    <p>模組內 mixinNum :{{mixinNum}}</p>
    <p>模組內 computedNum :{{computedNum}}</p>
    <button @click="conflicting">試試重複的methods,打開console</button>
  </div>`,
  data() {
    return {
      mixinNum: 0
    };
  },
  computed: {
    computedNum() {
      console.log("我是模組內原本的computedNum資料");
      return this.mixinNum + 20;
    }
  },
  methods: {
    conflicting() {
      console.log("模組內");
    }
  }
});

const vm = new Vue({
  el: "#vm",
  mixins: [Mymixin],
  data: {
    mixinNum: 10
  },
  computed: {
    computedNum() {
      console.log("我是根模組內原本computedNum資料");
      return this.mixinNum + 100;
    }
  },
  methods: {
    conflicting() {
      console.log("根模組");
    }
  }
});
</script>

在上面的例子中會發現: mixins 及模組內的數據資料如果發生衝突,最後一定是模組內的資料獲勝(得到的一定是模組內的資料),我自己理解為模組內的數據資料會直接取代掉 mixins 內的數據資料,以 conflicting() 得知在 console 中 mixinsconflicting() 連出現都沒有出現。

鉤子函數(lifecycle hooks)

<component-a></component-a>
<p>根模組 mixinNum :{{mixinNum}}</p>
<p>根模組 computedNum :{{computedNum}}</p>
<button @click="conflicting">試試重複的methods,打開console</button>
<script>
const Mymixin = {
  created() {
    console.log("我是被匯入(mixin)的資料");
    this.mixinData = "我是被匯入(mixin)的資料";
  }
};
Vue.component("component-a", {
  mixins: [Mymixin],
  template: `<div>
  </div>`,
  data() {
    return {
      mixinData: ""
    };
  },
  created() {
    console.log("我是模組內原本的資料");
    this.mixinData = "我是模組內原本的資料";
  }
});

const vm = new Vue({
  el: "#vm",
  mixins: [Mymixin],
  data: {
    mixinData: ""
  },
  created() {
    console.log("我是根模組內原本資料");
    this.mixinData = "我是根模組內原本的資料";
  }
});
</script>

最後 console 出現的順序如下圖

https://ithelp.ithome.com.tw/upload/images/20210128/20127553n4gcd9hAKk.png

在上面的例子中會發現: mixins 及模組內的鉤子函數都會被執行,但是模組的鉤子函數一定比 mixins 的晚出現,這代表模組的鉤子函數會去覆蓋 mixins 的,如果在鉤子函數中有資料被變更了,那麼就是 mixins 的鉤子函數會先將資料修改 → 模組的鉤子函數在修改一次資料,最終顯示的資料內容還是模組變更的那些。

Vue 在處理 mixins 跟模組數據資料及鉤子函數衝突時的不同:

發生衝突 數據資料 鉤子函數
mixins 不執行 執行
模組 執行 執行
處理方式 模組取代mixins 模組覆蓋mixins

全域註冊 mixin --不建議使用

因為會影響所有模組因為會影響所有模組(包含第三方插件),所以不建議使用全域註冊 mixin

Vue.mixin({
  // options
})

不須在模組內使用 mixins:[...] 載入了。

Demo:DAY18 | 跟 Vue.js 認識的30天 - Vue 模組混入(mixin) by Celeste6666

參考資料

Vue.js - 混入


上一篇
[DAY17]跟 Vue.js 認識的30天 - Vue 過渡(轉場)及動畫效果下篇(`<transition-group>`) - 多個元素的過渡及列表過渡
下一篇
[DAY19] 跟 Vue.js 認識的30天 - Vue 自定義指令(`directive`)
系列文
跟 VueJS 認識的30天21

尚未有邦友留言

立即登入留言