Реактивность и provide/inject
По умолчанию provide
и inject
во Vue не реактивны. Многим это не нравится. Многие хотели бы, чтобы они были реактивными. И хорошая новость в том, что добиться этого совсем несложно.
Но сначала подумайте
Описаные ниже техники нужно применять только в случае крайней необходимости. Не нужно использовать их как замену props
и events
.
data()
Способ №1: с помощью поля Любой объект, объявленный в поле data()
, будет реактивным. Следовательно, его реактивность будет сохраняться, независимо от того, где он используется. Вы можете даже передать его в какой-то javascipt модуль за пределами вашего приложения, и любые изменения этого объекта там вызовут обновление в вашем приложении. Так что мы можем просто записать вот таким образом:
export default {
data() {
return {
reactiveObject: {
value: "Hello world"
};
}
},
provide() {
return {
reactive: this.reactiveObject
};
}
};
observable
Способ №2: С помощью Начиная с версии 2.6 во Vue доступна функция observable
. Она позволяет создать реактивный объект. Собственно именно эту функцию Vue использует при добавлении реактивности к вашим данным в поле data()
. Давайте перепишем предыдущий пример с использованием функции observable
:
import Vue from "vue";
const reactiveObject = Vue.observable({value: "Hello world"});
export default {
provide() {
return {
reactive: reactiveObject
};
}
};
Способ №3: Использовать специальный плагин
Участник команды разработки Vue Thorsten Lünborg написал плагин, добавляющий реактивность к provide
. Исходный код доступен на github. Использовать его можно двумя способами.
Как плагин
Просто подключите его в файле main.js
import Vue from 'vue';
import ReactiveProvide from 'vue-reactive-provide';
Vue.use(ReactiveProvide);
Затем используйте в любом в компоненте, из которого хотите передать данные:
export default {
reactiveProvide: {
name: 'injectedName',
include: ['reactive'],
}
data() {
return {
reactive: 'hello',
};
},
};
И в компоненте, в котором хотите получить данные:
export default {
inject: ['injectedName']
};
Как миксин
Можно использовать как миксин. Тогда не нужно регистрировать плагин глобально.
import { ReactiveProvideMixin } from 'vue-reactive-provide'
export default {
mixins: [
ReactiveProvideMixin({
name: 'injectedName',
include: ['reactive'],
})
],
data() {
return {
reactive: 'hello',
};
},
};
Когда стоит использовать описанные способы
Помните, что лучше избегать добавления реактивности к provide/inject
. В большинстве случаев прекрасно работает стандартная схема обмена данными: пропсы вниз, события наверх. Она не добавляет в код лишних усложнений и сохраняет читабельность кода.