Explain the mixin strategy of Vue in detail

  • 2021-09-24 21:16:35
  • OfStack

Previously, I thought that the merging of mixin is based on the priority within the component, that is, if there is any conflict between the content of mixin and the content of the component, the content of the component shall prevail. This situation does exist, but the policy specified by vue is more detailed, and the merging strategy corresponding to each situation is recorded respectively below

Basic

When a component uses mixin, all mixin options will be mixed into the component's own options. This part has nothing to say, just look at the code


// define a mixin object
const myMixin = {
 created() {
  this.hello()
 },
 methods: {
  hello() {
   console.log('hello from mixin!')
  }
 }
}

// define an app that uses this mixin
const app = Vue.createApp({
 mixins: [myMixin]
})

app.mount('#mixins-basic') // => "hello from mixin!"

Consolidation policy for options

The options here refer to data, methods and lifecycle hook functions, which adopt different merging strategies

data, methods, components, directives will be merged into the same object, and the conflicting items will be subject to the component's


const myMixin = {
 data() {
  return {
   message: 'hello',
   foo: 'abc'
  }
 }
}

const app = Vue.createApp({
 mixins: [myMixin],
 data() {
  return {
   message: 'goodbye',
   bar: 'def'
  }
 },
 created() {
  console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" }
 }
})

const myMixin = {
 methods: {
  foo() {
   console.log('foo')
  },
  conflicting() {
   console.log('from mixin')
  }
 }
}

const app = Vue.createApp({
 mixins: [myMixin],
 methods: {
  bar() {
   console.log('bar')
  },
  conflicting() {
   console.log('from self')
  }
 }
})

const vm = app.mount('#mixins-basic')

vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

The hook function is not a simple replacement, if there are the same name, they will be merged into an array, and then called in turn, and mixin hook function will be called first


const myMixin = {
 created() {
  console.log('mixin hook called')
 }
}

const app = Vue.createApp({
 mixins: [myMixin],
 created() {
  console.log('component hook called')
 }
})

// => "mixin hook called"
// => "component hook called"

Global blending and customization options


const app = Vue.createApp({
 myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
 created() {
  const myOption = this.$options.myOption
  if (myOption) {
   console.log(myOption)
  }
 }
})

app.mount('#mixins-global') // => "hello!"

In the above code, we created a custom option globally, and then mixed it globally, but it should be noted that this will affect all subcomponents of this app:


const app = Vue.createApp({
 myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
 created() {
  const myOption = this.$options.myOption
  if (myOption) {
   console.log(myOption)
  }
 }
})

// add myOption also to child component
app.component('test-component', {
 myOption: 'hello from component!'
})

app.mount('#mixins-global')

// => "hello!"
// => "hello from component!"

We can see that this is not a simple replacement for custom options, but a separate call, although we can also formulate our own merge strategy:


const app = Vue.createApp({})

app.config.optionMergeStrategies.customOption = (toVal, fromVal) => {
 // return mergedVal
}

The merge policy accepts two parameters, which are the values of the specified items in the parent instance and the child instance. When using mixin, we can see what to print:


const app = Vue.createApp({
 custom: 'hello!'
})

app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
 console.log(fromVal, toVal)
 // => "goodbye!", undefined
 // => "hello", "goodbye!"
 return fromVal || toVal
}

app.mixin({
 custom: 'goodbye!',
 created() {
  console.log(this.$options.custom) // => "hello!"
 }
})

You can see the first print from mixin and then print from app.

Matters needing attention

mixin is very likely to cause conflicts, so you have to make sure that there are no conflicting attribute names to avoid conflicts, which will cause extra burden Reusability is limited, because mixin cannot accept parameters, so the logic is written and inflexible

Therefore, it is officially recommended to use Composition Api to organize logic

The above is a detailed explanation of Vue mixin strategy details, more information about Vue mixin strategy please pay attention to other related articles on this site!


Related articles: