В vue существует несколько форм общения:
- Родительский и дочерний компоненты излучают/включают
- Общее состояние в vuex
- Межкомпонентная шина событий
Упомянутый в документации режим Store редко обсуждается. Автор изучает организацию кода компонента Table в ElementUI, а такжеВаш собственный проект редактирования формы ElementUIПопрактиковавшись, я чувствую, что это очень полезно при организации сложных компонентов, и это метод коммуникации компонентов, которым пренебрегают.
Простой шаблон хранилища управления состоянием
Официальный пример кода:
var store = {
debug: true,
state: {
message: 'Hello!'
},
setMessageAction(newValue) {
if (this.debug) console.log('setMessageAction triggered with', newValue)
this.state.message = newValue
},
clearMessageAction() {
if (this.debug) console.log('clearMessageAction triggered')
this.state.message = ''
}
}
Официальное введение: все изменения состояния в магазине помещаются в собственные действия магазина для управления. Это централизованное управление состоянием упрощает понимание того, какие типы мутаций произойдут и как они будут запущены. Когда возникает ошибка, у нас также теперь есть журнал того, что произошло до ошибки. Кроме того, каждый экземпляр/компонент может по-прежнему владеть и управлять своим собственным частным состоянием.
Внедрение официальной версии слишком просто, давайте пойдем дальше и узнаем, как компонент Table в ElementUI использует Store для организации сложного компонента.
Зачем вам нужен режим магазина
Компонент Table в ElementUI имеет множество функций. Этот компонент состоит из родительского компонента Table.vue и множества дочерних компонентов layout-observer, table-body, table-column, table-footer, table-header, table-layout. Глядя на документацию ElementUI, компонент таблицы сложен.
Если события дочернего компонента передаются родительскому компоненту для обработки, сколько событий должен получить родительский компонент. И некоторые функции дочернего компонента будут влиять на макет родительского компонента. И некоторые данные таблицы требуются для большинства подкомпонентов. Вы хотите передать их по одному через Porp? Разработка потока данных сверху вниз затруднена. Эти общие данные лучше поместить в одно место, нам естественно легко думать о Vuex, но не считаете ли вы целесообразным внедрить ElementUI и внедрить Vuex из библиотеки ElementUI, а обмен данными только в табличном компоненте, а не глобальные данные, поэтому используется Store Шаблон не может быть лучше.
ElementUI имитирует использование Vuex. Заинтересованные читатели могут взглянуть на компонент Table.table-store.js
Одно из преимуществ имитации Vuex заключается в том, что если проект большой на более позднем этапе, Vuex можно внедрить очень плавно, а если вы знакомы с Vuex, использование режима Store не требует никаких когнитивных затрат.
упражняться
Автор использовал режим Store, чтобы преобразовать мой предыдущийРедактор онлайн-форм ElementUI, предыдущая главная страница состоит из области ресурсов элемента формы, области редактирования атрибутов формы, области перетаскивания элемента формы, области редактирования атрибутов элемента формы, области создания формы JSON и области создания кода. Однако вся страница поддерживает значения объекта формы, список элементов формы и свойства элемента формы.Однако эти значения играют определенную роль в нескольких подкомпонентах.Они не обрабатывались централизованно в начале, что приводит к неожиданным изменениям в данных. Я не знаю, вызвано ли это этим компонентом. После централизованной обработки в режиме Store логика кода становится намного понятнее.
Определяя и изолируя различные концепции управления состоянием и поддерживая независимость между представлениями и состоянием путем применения правил, наш код станет более структурированным и удобным для сопровождения.
объявить объект Store
const FormStore = function(form, initialState = {}) {
// 将父组件的示例保存在Store里面
if (!form) {
throw new Error('Form is required.')
}
this.form = form
this.states = { ... }
// initialState 里面的值必须是 this.states声明过的,这样所有状态的变化应该都在store里面可以查找,并由store控制
for (let prop in initialState) {
if (initialState.hasOwnProperty(prop) && this.states.hasOwnProperty(prop)) {
this.states[prop] = initialState[prop]
}
}
}
mutations
Мутации в Vuex очень похожи на события: каждая мутация имеет строковый тип события (тип) и функцию обратного вызова (обработчик). В этой функции обратного вызова мы фактически изменяем состояние, и она принимает состояние в качестве первого параметра.
Мы также имитируем его здесь, обратите внимание, что мы размещаем здесь только синхронный код, асинхронный код обрабатывает его сам.
FormStore.prototype.mutations = {
setFormAttribute(states, formAttribute) {
this.states = { ...states, formAttribute }
},
setFormItems(states, formItems) {
this.states = { ...states, formItems }
},
setClickedIndex(states, clickedIndex) {
this.states = { ...states, clickedIndex }
},
setFormItemToHandle(states, formItemToHandle) {
this.states = { ...states, formItemToHandle }
},
setItemInFormItems(states, idx, formItem) {
states.formItems.splice(idx, 1, formItem)
},
setFromItems(states, formItems) {
this.states = { ...states, formItems }
}
}
commit
Обмен данными между родительскими и дочерними компонентами сложных структур данныхemitа такжеv-onПоток событий подвержен путанице, особенно когда объекты вложены в объекты. При использовании режима Store между дочерним компонентом и родительским компонентом существует мост хранилища, а события распределяются через фиксацию.
В функции фиксации введитеconsole.log, изменения событий все в ваших руках. например, с помощью Vuex
// 定义
FormStore.prototype.commit = function(name, ...args) {
const mutations = this.mutations
console.log('emit', name)
if (mutations[name]) {
// states 作为第一个参数
mutations[name].apply(this, [this.states].concat(args))
} else {
throw new Error(`Action not found: ${name}`)
}
}
// 分发事件
this.store.commit('setFormItemToHandle', val)
использовать
Создайте хранилище данных родительского компонента, а затем передайте хранилище каждому дочернему компоненту. Логика кода очень понятна
data() {
const store = new FormStore(this);
return {
store
};
},
computed: {
form() {
return this.store.states.formAttribute;
}
},
methods: {
genFormItem(val) {
this.store.commit("setFormItemToHandle", val);
}
}
}
Режим магазина против EventBus
Преимущества Vuex — это преимущества режима Store
- Простота отладки и управления
- Подобно EventBus, хотя он не может отправлять события глобально и принимать события, в таком случае, почему бы не попробовать Vuex?
- Может применяться локально, с определенными обязанностями
EventBus в случае увеличения объема кода:
- Логика кода сильно сокращается, а читабельность снижается
- Для каждого родительского компонента действия требуется событие (или отправка) для обработки.
- Вам будет сложно найти, где срабатывает каждое событие, там полно бизнес-логики
Режим магазина против Vuex
Иногда мы можем не знать, использовать Vuex или нет, несмотря на слова автора Redux Дэна Абрамова:
Архитектура Flux похожа на очки: вы знаете, когда вам это нужно
Но у меня может быть только небольшая близорукость, и я могу делать это без очков, но я не могу ясно видеть вещи, и мне кажется, что носить очки немного громоздко.В настоящее время нам нужен наш режим магазина
Vuex отвечает за управление глобальным состоянием, а режим Store отвечает за передачу локального состояния.
Когда вы пишете большой компонент, режим Store можно использовать отдельно в компоненте, не помещая все данные в Vuex, в качестве моста для связи между несколькими дочерними компонентами и родительскими компонентами. У нашей компании в фоновом режиме десятки бизнесов, и под каждым бизнесом есть подразделения, если удобно писать компоненты, ставьте их вVuexвнутрь, тоVuexнасколько это будет раздуто
Когда развиваются несколько человек, бизнес каждого человека имеет отдельный Магазин и не будет влиять друг на друга.
Вы даже можете использовать несколько хранилищ, чтобы упорядочить весь свой код.
Суммировать
Имитируя Vuex, у нас есть новый способ организации сложных компонентов или управления локальным состоянием.Когда вы пишете сложные компоненты, вы не хотите загрязнять глобальный Vuex, и вам нужно разделить состояние между несколькими компонентами, вы можете учитывать Режим хранилища, такой же удобный, как Vuex, такой же легкий, как EventBus
Поскольку принята имитация Vuex, стиль кода должен быть реализован до конца, ведь режим Store не имеет сильных ограничений и не может быть похож на ElementUI, а также в коде есть прямые модификации оператора состояний (escape).
eg:
this.store.states.treeData = this.getTableTreeData(value);
Испытайте мой проект редактора форм ElementUI, основанный на преобразовании режима Store, не забудьте указать маленькую звезду,Посмотреть адрес проекта