[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>`) - 多个元素的过渡及列表过渡

>>:  [Android Studio] -- Day 1 引言

16 | WordPress 地图区块 Map Block

使用地图区块,可将地图嵌入网站上的任何文章或页面之内。 若要新增地图区块,请按一下区块插入工具图示。...

[Day4] 学 Bootstrap 是为了走更长远的路 ~ 基本篇

前言 昨天的文章有提到接下来会介绍几个 Bootstrap 我到现在还是很常用的语法, 但你可能会说...

【领域展开 18 式】 我的 Bluehost 帐密不是我 WordPress 的帐密

因缘际会,写这次铁人赛内容时会使用不同台电脑做登入操作 WordPress 上的功能,因此会开设无痕...

Day08 - 套用 Html Helper - 复杂型别 object + collection

Case01 跟 Day05 范例差不多,差异如下: Controller 於 Get 时,先写死固...

【把玩Azure DevOps】Day16 Artifacts应用:让外部合作夥伴也可以从Private nuget安装Package

前面几篇文章都在提Azure DevOps Artifacts,也就是如何利用这个服务来达成私有化的...