Примеси (mixins) — это гибкий инструмент повторного использования кода в компонентах Vue. Объект примеси может содержать любые настройки компонентов. При использовании компонентом примеси, все настройки примеси «подмешиваются» к собственным настройкам компонента.
Пример:
// определяем объект примеси
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('привет из примеси!')
}
}
}
// определяем компонент, использующий примесь
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "привет из примеси!"
Если примесь и компонент содержат пересекающиеся настройки, они будут определённым образом объединены.
Например, объект data
претерпевает рекурсивное слияние с объектом data
компонента, который имеет приоритет в случаях конфликтов.
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" }
}
})
Функции перехватчиков с одинаковыми именами объединяются в массив, чтобы все они вызывались. Перехватчики примеси будут вызываться перед собственными перехватчиками компонента.
var mixin = {
created: function () {
console.log('вызван перехватчик примеси')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('вызван перехватчик компонента')
}
})
// => "вызван перехватчик примеси"
// => "вызван перехватчик компонента"
Настройки, ожидающие значения в форме объектов, такие как methods
, components
и directives
будут объединены. В случае конфликта, приоритет имеют настройки компонента:
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('из примеси')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('из самого компонента')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "из самого компонента"
Обратите внимание, что те же самые стратегии слияния используются и во Vue.extend()
.
Примесь может быть применена и глобально. Но используйте данную возможность осторожно! После применения, примесь окажет влияние на все экземпляры Vue, создаваемые в дальнейшем. При правильном использовании это можно использовать для вставки логики обработки пользовательских настроек:
// добавляем обработчик для пользовательской настройки `myOption`
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"
Используйте глобальные примеси с осторожностью, поскольку они влияют на все до единого создаваемые экземпляры Vue, включая внешние компоненты. В большинстве случаев их стоит использовать только для обработки пользовательских настроек, подобно примеру выше. Неплохой идеей будет их оформление в виде добавок, что позволит избежать дублирования кода.
При слиянии пользовательских настроек применяется стратегия по умолчанию, которая просто заменяет одни значения другими. Если вы хотите использовать пользовательскую логику при слиянии пользовательских настроек, добавьте функцию в Vue.config.optionMergeStrategies
:
Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
// return mergedVal
}
Для большей части настроек-объектов можно просто использовать стратегию, применяемую по умолчанию для настройки 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)
}
}