Углубленный принцип vuex (ниже)

Vuex

предисловие

существуетУглубленный принцип vuex (вкл.)В разделе мы ответили на вопрос «как хранилище vuex внедряется в компонент?», давайте продолжим изучение следующих вопросов!

  • Как состояние и геттер vuex сопоставляются с автоматическим обновлением каждого экземпляра компонента?

В этой статье в основном обсуждается вопрос о том, «как состояние и геттер vuex сопоставляются с автоматическим обновлением каждого экземпляра компонента?». Во-первых, давайте кратко разберем проблему!


Примечание: В этой статье показан только основной код ядра.Во-первых, из-за недостатка места, а во-вторых, код ядра легче понять! Кроме того, эта статья относится к продвинутой статье vuex, и я не буду вдаваться в подробности о связанных с vue механизмах, задействованных в этой статье, и о продвинутом использовании vuex! Пожалуйста, перейдите на официальный сайт, чтобы проверить это!


Подготовить

Вопрос: Как состояние и геттер vuex сопоставляются с каждым экземпляром компонента и автоматически обновляются?

Анализ проблемы

Основная проблема этой проблемы заключается в том, что когда состояние и методы получения в хранилище изменяются, как vuex гарантирует, что данные в каждом экземпляре компонента автоматически обновляются, и компонент обновляется! Короче говоря, когда хранилище компонентов обновляется, как уведомить другие компоненты об обновлении данных и обновлении пользовательского интерфейса! Путем простого анализа мы видим, что корень проблемы — проблема взаимодействия компонентов!

Говоря о компонентной коммуникации

Из анализа, чтобы ответить на этот вопрос, нам нужно начать с общения компонентов vue! В процессе использования Vue требуется частая связь между компонентами! Отношения между субъектами коммуникации могут быть компонентами родитель-потомок или неродительско-дочерними компонентами, такими как родственные компоненты или несвязанные компоненты. В общем, есть несколько способов следующим образом!

  1. Передать данные дочерним компонентам через реквизит: родитель -> дочерний
  2. Отправьте сообщение на родительский компонент по событию: Ребенок -> Родитель, используйте $ emit Отправить события
  3. Родительская цепочка и дочерний индекс:this.$parentа такжеthis.$children
  4. Внедрение зависимостей: предоставить и внедрить
  5. Ссылки на дочерние компоненты: ref и $refs
  6. Привязка функций:v-bind="$attrs"а такжеv-on="$listeners"
  7. event bus
  8. $dispatch 和 $broadcast: Использование vue1
  9. Используйте глобальные переменные, хранилище, файлы cookie, запросы, хэши и т. д. для передачи данных: функции, отличные от Vue, не вдавайтесь в подробности.
  10. глобальная трансляция событий

На следующем рисунке показан метод связи компонентов для вышеуказанных схем 1–6.

vue 组件通信

Так как схема 8 официально не рекомендуется для использования в vue2, то здесь она повторяться не будет, а схемы с 9 по 10 не являются фичами vue, а являются общими схемами передачи данных во внешнем интерфейсе, и здесь повторяться не будут! Если у вас есть другие планы, пожалуйста, добавьте их!

Ниже мы в основном представляем решение 7, решение для центральной шины событий, которое тесно связано с содержанием этой статьи! Его основная идея дизайна состоит в том, чтобы представить центральный коммуникационный мост - центральную шину событий, чтобы каждый компонент мог общаться только с ней, чтобы достичь цели связи синхронизации данных! Как показано на рисунке ниже, данные компонента A изменяются, и центральная шина событий уведомляется, а другие компоненты прослушивают и получают измененные данные.

vue中央事件总线

В следующем коде показано использование центральной шины событий для взаимодействия компонентов в 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 (emit 与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的state与getter实现原理

  1. Состояние vuex реализуется с помощью отзывчивых данных vue.
  2. Геттер реализован с помощью вычисляемого свойства Vue.
  3. Идея его дизайна точно такая же, как у центральной шины событий Vue.

Чтобы узнать больше о принципах vuex, перейдите по ссылкеУглубленный принцип vuex (вкл.)