предисловие
существуетУглубленный принцип vuex (вкл.)В разделе мы ответили на вопрос «как хранилище vuex внедряется в компонент?», давайте продолжим изучение следующих вопросов!
- Как состояние и геттер vuex сопоставляются с автоматическим обновлением каждого экземпляра компонента?
В этой статье в основном обсуждается вопрос о том, «как состояние и геттер vuex сопоставляются с автоматическим обновлением каждого экземпляра компонента?». Во-первых, давайте кратко разберем проблему!
Примечание: В этой статье показан только основной код ядра.Во-первых, из-за недостатка места, а во-вторых, код ядра легче понять! Кроме того, эта статья относится к продвинутой статье vuex, и я не буду вдаваться в подробности о связанных с vue механизмах, задействованных в этой статье, и о продвинутом использовании vuex! Пожалуйста, перейдите на официальный сайт, чтобы проверить это!
Подготовить
Вопрос: Как состояние и геттер vuex сопоставляются с каждым экземпляром компонента и автоматически обновляются?
Анализ проблемы
Основная проблема этой проблемы заключается в том, что когда состояние и методы получения в хранилище изменяются, как vuex гарантирует, что данные в каждом экземпляре компонента автоматически обновляются, и компонент обновляется! Короче говоря, когда хранилище компонентов обновляется, как уведомить другие компоненты об обновлении данных и обновлении пользовательского интерфейса! Путем простого анализа мы видим, что корень проблемы — проблема взаимодействия компонентов!
Говоря о компонентной коммуникации
Из анализа, чтобы ответить на этот вопрос, нам нужно начать с общения компонентов vue! В процессе использования Vue требуется частая связь между компонентами! Отношения между субъектами коммуникации могут быть компонентами родитель-потомок или неродительско-дочерними компонентами, такими как родственные компоненты или несвязанные компоненты. В общем, есть несколько способов следующим образом!
- Передать данные дочерним компонентам через реквизит: родитель -> дочерний
- Отправьте сообщение на родительский компонент по событию: Ребенок -> Родитель, используйте $ emit Отправить события
- Родительская цепочка и дочерний индекс:
this.$parent
а такжеthis.$children
- Внедрение зависимостей: предоставить и внедрить
- Ссылки на дочерние компоненты: ref и $refs
- Привязка функций:
v-bind="$attrs"
а такжеv-on="$listeners"
- event bus
-
$dispatch 和 $broadcast
: Использование vue1 - Используйте глобальные переменные, хранилище, файлы cookie, запросы, хэши и т. д. для передачи данных: функции, отличные от Vue, не вдавайтесь в подробности.
- глобальная трансляция событий
На следующем рисунке показан метод связи компонентов для вышеуказанных схем 1–6.
Так как схема 8 официально не рекомендуется для использования в vue2, то здесь она повторяться не будет, а схемы с 9 по 10 не являются фичами vue, а являются общими схемами передачи данных во внешнем интерфейсе, и здесь повторяться не будут! Если у вас есть другие планы, пожалуйста, добавьте их!
Ниже мы в основном представляем решение 7, решение для центральной шины событий, которое тесно связано с содержанием этой статьи! Его основная идея дизайна состоит в том, чтобы представить центральный коммуникационный мост - центральную шину событий, чтобы каждый компонент мог общаться только с ней, чтобы достичь цели связи синхронизации данных! Как показано на рисунке ниже, данные компонента A изменяются, и центральная шина событий уведомляется, а другие компоненты прослушивают и получают измененные данные.
В следующем коде показано использование центральной шины событий для взаимодействия компонентов в vue!
let bus = new Vue({
methods: {
emit (event, ...args) {
this.$emit(event, ...args);
},
on (event, callback) {
this.$on(event, callback);
}
}
});
//component A
bus.emit('updateData', data); // 发送数据给 bus。
//component B
bus.on('updateData', data => {
// 接收 updateData事件 发送的数据信息。
})
Реализация центрального события VUE - это просто создать новый объект Vue, с помощью характеристик объекта Vue (on) в качестве коммуникационного моста для других компонентов для реализации связи и обмена данными между компонентами!
Изучение принципа
Эта часть ответит на вышеуказанные вопросы, проанализирует основной код с помощью анализа исходного кода и ответит на вопросы.
использоватьМы обсуждаем состояние и геттер.Для начала давайте посмотрим, как легко получить состояние и геттер vuex в компоненте vue!
this.$store.state.xxx;
this.$store.state.moduleA.xxx;
this.$store.getters.xxx;
this.$store.getters.moduleA.xxx;
Как мы знаем, хранилище vuex будет разделено на две области данных: состояние и геттеры. Геттер — это состояние, полученное из состояния хранилища! код показывает, как показано ниже:
// 初始化store时,划分出 state数据区 与 getters数据区
new Vuex.Store({state, getters});
Анализ исходного кода
Во-первых, давайте посмотрим на состояние. В исходном коде мы нашли метод получения состояния следующим образом:
get state () {
return this._vm._data.?state
}
Из исходного кода известно, что он используется в компоненте vue.this.$store.getters.xxx
Получатьxxx
атрибут, он фактически полученstore._vm.data.?state
Одноименное свойство объекта. Затем мы сосредоточимся на _vm. Мы нашли основную функцию обработки состояния и геттера через конструктор StoreresetStoreVM(this, state)
. Его основной код выглядит следующим образом:
store._vm = new Vue({
data: {
?state: state
}
})
Приведенный выше код инициализирует экземпляр Vue _VM. Поскольку данные Vue отзывчиваются,? Состояние также отзывчиво, поэтому, когда мы обновляем STATE.xxx в экземпляре компонента, ответ на основе данных Vue, значение Value.xxx всех связанных компонентов будет Будьте обновлены автоматически, а пользовательский интерфейс также будет обновляться автоматически! Видно, что это точно так же, как и идея дизайна проектирования центральной шины событий Vuue. Он также использует характеристики Vue Objects (адаптивные данные) в качестве моста связи для других компонентов для реализации связи и совместного использования данных между компонентами!
Суммировать
Состояние vuex реализуется с помощью отзывчивых данных vue. Идея дизайна та же, что и у центрального автобуса событий Vue!
догадка
Вычисляемые свойства в vue получаются из данных, а геттеры в vuex — это свойства, производные от состояния; а состояние в vuex реализуется с помощью данных, так реализуется ли геттер с помощью вычисляемых?
Проверка исходного кода
Вы можете увидеть обработку wrapGetters (обернутые, собранные геттеры, игнорирование деталей обработки) в resetStoreVM.
const computed = {};
// 处理getters
forEachValue(wrappedGetters, (fn, key) => {
computed[key] = () => fn(store) // 将getter存储在computed上
//this.$store.getters.XXX的时候获取的是store._vm.XXX
Object.defineProperty(store.getters, key, {
get: () => store._vm[key],
enumerable: true
})
})
Код обработки wrapGetters, хранилище для создания вычисляемых объектов геттером, давайте сосредоточимся на последующем процессе, который может быть вычислен!
store._vm = new Vue({
computed
})
Вышеприведенный код связывает вычисляемый объект с вычисляемым свойством экземпляра Vue _vm, используя характеристики вычислительных свойств Vue, и изменение данных также может быть синхронизировано с другими связанными компонентами. Это согласуется с нашим предположением! Getter реализован с вычисленными характеристиками Vue!
Анализ до сих пор, мы пришли к ответу на этот вопрос!
В заключение
- Состояние vuex реализуется с помощью отзывчивых данных vue.
- Геттер реализован с помощью вычисляемого свойства Vue.
- Идея его дизайна точно такая же, как у центральной шины событий Vue.
Чтобы узнать больше о принципах vuex, перейдите по ссылкеУглубленный принцип vuex (вкл.)