Vue 3.0 混入

2021-07-16 11:41 更新

#基礎(chǔ)

混入 (mixin) 提供了一種非常靈活的方式,來分發(fā) Vue 組件中的可復(fù)用功能。一個混入對象可以包含任意組件選項(xiàng)。當(dāng)組件使用混入對象時,所有混入對象的選項(xiàng)將被“混合”進(jìn)入該組件本身的選項(xiàng)。

例子:

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

#選項(xiàng)合并

當(dāng)組件和混入對象含有同名選項(xiàng)時,這些選項(xiàng)將以恰當(dāng)?shù)姆绞竭M(jìn)行“合并”。

比如,數(shù)據(jù)對象在內(nèi)部會進(jìn)行遞歸合并,并在發(fā)生沖突時以組件數(shù)據(jù)優(yōu)先。

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

同名鉤子函數(shù)將合并為一個數(shù)組,因此都將被調(diào)用。另外,混入對象的鉤子將在組件自身鉤子之前調(diào)用。

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


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


// => "混入對象的鉤子被調(diào)用"
// => "組件鉤子被調(diào)用"

值為對象的選項(xiàng),例如 methods、componentsdirectives,將被合并為同一個對象。兩個對象鍵名沖突時,取組件對象的鍵值對。

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"

#全局混入

你還可以為 Vue 應(yīng)用程序全局應(yīng)用 mixin:

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


// 為自定義的選項(xiàng) 'myOption' 注入一個處理器。
app.mixin({
  created() {
    const myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})


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

混入也可以進(jìn)行全局注冊。使用時格外小心!一旦使用全局混入,它將影響每一個之后創(chuàng)建的組件 (例如,每個子組件)。

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


// 為自定義的選項(xiàng) 'myOption' 注入一個處理器。
app.mixin({
  created() {
    const myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})


// 將myOption也添加到子組件
app.component('test-component', {
  myOption: 'hello from component!'
})


app.mount('#mixins-global')


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

大多數(shù)情況下,只應(yīng)當(dāng)應(yīng)用于自定義選項(xiàng),就像上面示例一樣。推薦將其作為插件發(fā)布,以避免重復(fù)應(yīng)用混入。

#自定義選項(xiàng)合并策略

自定義選項(xiàng)將使用默認(rèn)策略,即簡單地覆蓋已有值。如果想讓自定義選項(xiàng)以自定義邏輯合并,可以向 app.config.optionMergeStrategies 添加一個函數(shù):

const app = Vue.createApp({})


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

合并策略接收在父實(shí)例和子實(shí)例上定義的該選項(xiàng)的值,分別作為第一個和第二個參數(shù)。讓我們來檢查一下使用 mixin 時,這些參數(shù)有哪些:

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 打印 toValfromVal,然后從 app 打印。如果存在,我們總是返回 fromVal,這就是為什么 this.$options.custom 設(shè)置為 你好! 最后。讓我們嘗試將策略更改為始終從子實(shí)例返回值:

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


app.config.optionMergeStrategies.custom = (toVal, fromVal) => toVal || fromVal


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

在 Vue 2 中,mixin 是將部分組件邏輯抽象成可重用塊的主要工具。但是,他們有幾個問題:

  • mixin 很容易發(fā)生沖突:因?yàn)槊總€特性的屬性都被合并到同一個組件中,所以為了避免 property 名沖突和調(diào)試,你仍然需要了解其他每個特性。
  • 可重用性是有限的:我們不能向 mixin 傳遞任何參數(shù)來改變它的邏輯,這降低了它們在抽象邏輯方面的靈活性

為了解決這些問題,我們添加了一種通過邏輯關(guān)注點(diǎn)組織代碼的新方法:組合式 API。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號