Contamination


Directory

  • ##Basics

  • Option merge

  • Global mixin

  • Custom option merge Strategy


Basics


mixin ) provides a very flexible way to distribute reusable functionality in Vue components. A mixin can contain arbitrary component options. When a component uses a mixin, all of the mixin's options will be "mixed" into the options of the component itself.

Example:

// 定义一个混入对象
var myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    }
  }
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
  mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"


Option merge


When components and When a mixin object contains options with the same name, these options will be "merged" in the appropriate manner.


For example, data objects are merged recursively internally, and component data takes precedence when conflicts occur.

var mixin = {
  data: function () {
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}
new Vue({
  mixins: [mixin],
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "goodbye", foo: "abc", bar: "def" }
  }
})

Hook functions with the same name will be merged into an array, so they will all be called. In addition, the hook of the mixed object will be called

before the component's own hook . Options whose

var mixin = {
  created: function () {
    console.log('混入对象的钩子被调用')
  }
}
new Vue({
  mixins: [mixin],
  created: function () {
    console.log('组件钩子被调用')
  }
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"

values ​​are objects, such as

methods, components, and directives, will be merged into the same object. When the key names of two objects conflict, the key-value pair of the component object is taken.

var mixin = {
  methods: {
    foo: function () {
      console.log('foo')
    },
    conflicting: function () {
      console.log('from mixin')
    }
  }
}
var vm = new Vue({
  mixins: [mixin],
  methods: {
    bar: function () {
      console.log('bar')
    },
    conflicting: function () {
      console.log('from self')
    }
  }
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

Note:

Vue.extend() also uses the same strategy for merging.


Global mix-in


Mix-ins can also be registered globally. Use with extreme caution! Once a global mixin is used, it will affect

every subsequently created Vue instance. When used appropriately, this can be used to inject processing logic for custom options.

// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})
new Vue({
  myOption: 'hello!'
})
// => "hello!"

Please use global mixins with caution as it affects every individually created Vue instance (including third-party components). In most cases, this should only be applied to custom options, like the example above. It is recommended to publish it as a

plugin to avoid repeated application mixins.


Custom option merge strategy


Custom options will use the default strategy, which is to simply overwrite the existing value. If you want custom options to be merged with custom logic, you can add a function to

Vue.config.optionMergeStrategies:

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

For options whose values ​​are mostly objects, you can use

methods The same merge strategy:

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

A more advanced example can be found in

Vuex 1.x's mix-in strategy:

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