Vue 之 Mixins (混入)

Vue 之 Mixins (混入)

Mixins

Mixins是一种分发Vue组件中可复用功能的非常灵活的一种方式。

什么时候使用Mixins

页面的风格不用,但是执行的方法和需要的数据类似,我们是选择每个都写呢还是提取出公共部分呢?

基础实例

我们有一对不同的组件,它们的作用是切换一个状态布尔值,一个模态框和一个提示框。这些提示框和模态框除了在功能上,没有其他共同点:它们看起来不一样,用法不一样,但是逻辑一样。

// 模态框
const Modal = {
  template: '#modal',
  data() {
    return { isShowing: false } }, methods: { toggleShow() { this.isShowing = !this.isShowing; } }, components: { appChild: Child } } // 提示框 const Tooltip = { template: '#tooltip', data() { return { isShowing: false } }, methods: { toggleShow() { this.isShowing = !this.isShowing; } }, components: { appChild: Child } } 

解决办法如下:

const toggle = {
    data () {
        isshowing: false
    },
    methods: {
        toggleShow() {
            this.isshowing = !this.isshowing } } } // 下面即可使用了 // mixins: [变量名] const Modal = { template: '#modal', mixins: [toggle], components: { appChild: Child } } const Tooltip = { template: '#tooltip', mixins: [toggle], components: { appChild: Child } } 

选项合并

当组件和混入对象含有同名选项时,这些选项会以恰当的方式混合。 比如数据对象在内部会进行浅合并(一层属性的深度),在和组件的数据发生冲突时,以组件数据优先。

var mixin = {
  data() {
    return {
      msg_mixins: 'mixins',
      msg: '123' } } } var app = new Vue({ el: '#app', mixins: [mixin], data: { msg: 'app' }, created: function ( ) { console.log(this.$data) // => { "msg": "app", "msg_mixins": "mixins" } } }) 

同名的钩子函数将混合为一个数组,所以都会被调用,另外,混入对象的钩子函数会在组件自身的钩子函数之前先进行调用。

var mixin = {
  data() {
    return {
      msg_mixins: 'mixins',
      msg: '123' } }, created: function ( ) { console.log('混入对象的钩子被调用') } } var app = new Vue({ mixins: [mixin], el: '#app', data: { msg: 'app' }, created: function ( ) { console.log('组件钩子被调用') } }) 
混入对象的钩子被调用
组件钩子被调用
vue.js:9058 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html

当混合值为对象的选项,例如 methods,components,directive,将被混合为同一个对象,两个对象键名冲突时,取组件的。

混入对象的钩子被调用
merge3.html:47 组件钩子被调用
vue.js:9058 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
app.foo
ƒ () {
          console.log('foo')
        }
app.foo
ƒ () {
          console.log('foo')
        }
app.conflicting
ƒ () {
          console.log('from self')
        }

注意:Vue.extend() (扩展)也使用同样的策略进行合并。

全局混入

我们也可以进行全局注册混入对象,注意使用。一旦使用全局混入对象,将会影响所有你创建的 vue 实例,如果使用恰当可以对自定义的对象注入逻辑。比如全局的判断等,会方便一些,不需要每个页面判断,直接取值就行了。

Vue.mixin({
  created: function ( ) {
      console.log('全局混入') } }) var mixin = { data() { return { msg_mixins: 'mixins', msg: '123' } }, created: function ( ) { console.log('混入对象的钩子被调用') }, methods: { foo: function ( ) { console.log('foo') }, conflicting: function ( ) { console.log('from mixin') } } } var app = new Vue({ mixins: [mixin], el: '#app', data: { msg: 'app' }, created: function ( ) { console.log('组件钩子被调用') }, methods: { bar: function ( ) { console.log('bar') }, conflicting: function ( ) { console.log('from self') } } }) 
全局混入
mixin.html:34 混入对象的钩子被调用
mixin.html:53 组件钩子被调用
vue.js:9058 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html

谨慎使用全局混入对象,因为会影响到每个单独创建的 Vue 实例 (包括第三方模板)。大多数情况下,只应当应用于自定义选项。也可以将其用作 Plugins 以避免产生重复应用。

自定义选项合并策略

自定义选项使用默认策略,就是简单的覆盖默认值。如果想让自定义选项以自定义的逻辑合并, 可以向 Vue.config.optionMergeStrategies 添加一个函数:

Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
  // 返回合并后的值
}

也就是说,本来的选项的合并方式是默认的,但是我们可以通过修改添加一个函数,来修改合并的方式逻辑。

对于大多数的合并策略来说,可以使用 methods:

var strategies = Vue.config.optionMergeStrategies
strategies.myOption = strategies.methods

可以在 Vuex 1.x 的混入策略里找到一个更高级的例子:

const merge = Vue.config.optionMergeStrategies.computed
Vue.config.optionMergeStrategies.vuex = function (toVal, fromVal) {
  if (!toVal) return fromVal if (!fromVal) return toVal return { getters: merge(toVal.getters, fromVal.getters), state: merge(toVal.state, fromVal.state), actions: merge(toVal.actions, fromVal.actions) } }

猜你喜欢

转载自www.cnblogs.com/xuzhenlei/p/12410732.html