1. 程式人生 > 程式設計 >詳解Vue的mixin策略

詳解Vue的mixin策略

我之前一直以為mixin的合併是以元件內的優先,即mixin的內容如果和元件內有衝突的,以元件內為準,確實存在這種情況,但是vue指定的策略更詳細,下面分別記錄各種情況對應的合併策略

基本

當一個元件使用mixin的時候,所有mixin的選項會被混入到元件自己的選項中, 這部分沒什麼好說的,直接看程式碼

// 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!"

選項的合併策略

這裡的選項指的就是 data methods和生命週期鉤子函式這些選項,他們的會採取不同的合併策略

像data,methods,components,directives這樣的會被合併進同一個物件中,並且遇到衝突項以元件的為準

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"

而對於鉤子函式就不是簡單的替換了,如果有同名的,他們會被一起合併進陣列中,然後依次呼叫,且mixin的鉤子函式會率先被呼叫

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"

全域性混入和自定義選項

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!"

上述程式碼,我們在全域性建立了一個自定義選項,然後進行了全域性混入處理,但是需要注意的是,這會影響到這個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!"

我們可以看到,對於自定義選項這不是簡單的替換,而是分別呼叫,當然我們也可以制定我們自己的合併策略:

const app = Vue.createApp({})

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

合併策略接收兩個引數,分別是指定項在父例項和子例項的值,當使用mixin的時候我們可以檢視列印什麼:

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

可以看到第一次從mixin列印,然後從app列印。

注意事項

  • mixin很容易造成衝突,你得確保不會有衝突的屬性名,來避免衝突,這會造成額外的負擔
  • 複用性有限,因為mixin不能接受引數,所以邏輯是寫定的,不靈活

所以官方推薦使用 Composition Api來組織邏輯

以上就是詳解Vue的mixin策略的詳細內容,更多關於Vue的mixin策略的資料請關注我們其它相關文章!