Несколько дней назад друг спросил в группе, что vue.$emit и $on могут обеспечивать глобальную связь между компонентами.Разве это не полная замена vuex, зачем использовать vuex?
Эта проблема начинается с происхождения шины событий eventbu s и vuex.
(Пока Youda vue3.0 все еще в пути, давайте приготовим жареный рис)
компонент связи
Давным-давно в королевстве Vue была компонентная башня, была компонентная семья, A, B, C, компонентный отец A и сын B, C жили на разных уровнях, они были очень далеко друг от друга.
родитель -> ребенок
В это время отец скучает по сыну и хочет отправить ему письмо, что делать? Простой! На каждом дочернем компоненте есть пропс "почтовый ящик", через который отец может напрямую доставлять почту (данные)
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="我是父亲的消息!"></blog-post>
ребенок -> родитель
Получив письмо от отца, Б и С очень обрадовались. Я хочу перезвонить отцу.В это время выходит белый голубиный мессенджер vue.$emit, а подкомпонент использует vue.$emit для передачи сообщения и его распространения на верхний уровень.
this.$emit("todo",{
res:"我是儿子的消息"
})
Получив сообщение, отец должен по-разному реагировать на различные типы информации, отправленной сыном.
this.$on('todo',function(data){
// todo
//data => 来自儿子的消息
})
родной брат
A часто обучает B и C, говоря, что между братьями должно быть больше контактов, чтобы усилить привязанность, но $emit может передавать сообщения только на верхний уровень, как должны общаться два брата, живущие на одном этаже?
шина событий eventbu
В это время один мудрый человек придумал метод: если вы все используете метод $emit, почему бы мне напрямую не открыть SF Express? В это время вышла шина событий vue eventbus.С помощью экземпляра vue, который был свободен за пределами башни компонента, была построена шина шины, и сообщение сына было отправлено в шину шины через $emit.
B.$root.bus.$emit('todo')
В это время сообщение, полученное отцом, отправляется по автобусной шине, и устанавливается ответное событие.
A.$root.bus.on('todo',function(){})
Чтобы отец и сын могли легко общаться друг с другом
Самый важный вопрос: как братья общаются?
В это время из автобуса выскочил мудрец и сказал, что клиент - это Бог, будь то отец или сын, может использовать наш автобус SF Express, который также реализует связь между компонентами-братьями.
B.$root.bus.$emit('todo')
// 兄弟C也能收到这个消息
C.$root.bus.on('todo',function(){})
problem?
А пока вернемся к ключевому моменту этой статьи: почему мы до сих пор используем vuex для такой хорошей штуки, как eventBus?
Следующее содержимое относится к vuex-basics-tutorial
В начале наш проект может быть таким простым, как этот
1. 代码逻辑性极具下降,可阅读性变低
2. 对于每一个action父组件都需要一个on(或dispatch)一个事件来处理
3. 你将很难查找到每一个事件是从哪里触发,满篇都是业务逻辑
простой пример
Возьмем простой пример. В вашей компании изначально был компонент отображения, и его роль заключалась в отображении текущего значения приращения в корневом компоненте приложения. Вы нанимаете двух новых сотрудников и назначаете им две задачи.
- Вы позволяете Xiao A разработать новый счетчик и использовать его в новом компоненте (childDisplay), понимаете, что один щелчок увеличивает приращение один раз, и отображаете текущее количество приращений в компоненте. Этот счетчик подписан на увеличение, и щелчок по счетчику приводит к тому, что display и childDisplay отображают увеличенное число на 1.
Сяо А с радостью и быстро выполнил фиксацию задачи, а затем нажал - Вы сказали Xiao B, что мне нужен компонент кнопки, этот компонент кнопки генерирует событие сброса для экземпляра приложения, это событие сбрасывает приращение в приложении до 0
Ладно, малыш Б тоже с радостью совершает и пушит - В это время вы обнаружите, что когда вы нажимаете на компонент A, число после приращения успешно отображается как на дисплее, так и на childDiplay, но когда вы нажимаете на компонент B, чтобы вызвать событие сброса, приращение на корневом компоненте равно сбрасывается на 0, но из-за малого B не знает, что компонент A также подписывается на данные приращения, в результате чего состояние компонента A не обновляется.
vuex
Чтобы предотвратить эти проблемы, в это время встал король Ю Сяою.С помощью мыслей соседнего Королевства Потоков он повел мудрецов по всей стране изучать новый способ решения этой хаотичной проблемы. Это векс.
По определению
- store — это склад, на складе хранятся данные проекта (store.state)
- (Строгий режим) Чтобы решить проблему невозможности отслеживания изменений состояния, данные в хранилище не изменяются напрямую путем изменения store.state, а передаются в хранилище через действие фиксации, и будет сообщено об ошибке.[vuex] Do not mutate vuex store state outside mutation handlers
- После того, как хранилище получит действие фиксации, оно найдет соответствующее событие в store.mutation и изменит store.state.
Вернемся к простому примеру
Решение 1 (Простой режим магазина)
Чтобы решить вышеуказанные проблемы, мы внесли несколько интересных изменений. (состояние)
- Определить постоянное хранилище в хранилище
- Переменная с именем sharedState определена в локальных данных, которые являются отображением в store.state.
- Поскольку sharedState является данными vue, это делает store.state также чувствительными данными.Когда данные в store.state изменяются, vue автоматически обновляет данные в sharedState.
Таким образом, исходная проблема решается, а инкремент, на который подписан компонент А и компонент Б, — это уже не данные о корневом компоненте, а данные хранилища. Когда данные хранилища изменяются, vue автоматически обновляет каждый компонент, который подписывается на данные приращения.
// 这是父级display组件
<template>
Count is {{ sharedState.counter }}
</template>
<script>
import store from '../store'
export default {
data () {
return {
sharedState: store.state
}
}
}
</script>
// 这是A组件
import store from '../store'
<template>
Count is {{ sharedState.counter }}
</template>
export default {
data () {
return {
sharedState: store.state
}
},
methods: {
activate () {
this.sharedState.counter += 1
}
}
}
// 这是B组件
import store from '../store'
export default {
data () {
return {
sharedState: store.state
}
},
methods: {
reset () {
this.sharedState.counter = 0
}
}
}
Вариант 1 вариант
Является ли вышеописанный метод лучшим? Представьте, что А и Б покинули компанию после разработки многочисленных компонентов сброса и счетчиков. В это время был нанят новый сотрудник C. Вы сказали C, что я хочу, чтобы все инкременты были размером не более 100. Нужно ли C рефакторить все компоненты и судить о размере? Это очень смешной выбор. Это когда мы представили новый метод. (мутация)
var store = {
state: {
counter: 0
},
increment: function () {
if (store.state.counter < 100) {
store.state.counter += 1;
}
},
reset: function () {
store.state.counter = 0;
}
}
export default store
Согласно приведенному выше выводу, vuex медленно обретает форму.
Мы воссоздаем store.jsimport Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
var store = new Vuex.Store({
state: {
counter: 0
},
mutations: {
INCREMENT (state) {
state.counter ++
}
}
})
export default store
Давайте посмотрим, что здесь происходит
- Мы представили модуль vuex и активировали его как плагин vue.
- Наш склад-хранилище больше не является обычным jsonObject, а является экземпляром vuex.store.
- Использование мутации для изменения состояния
why better ?
- Если мы сохраняем копии всех состояний во время разработки, мы можем отлаживать код как супергерой во времени и пространстве, записывая каждое изменение состояния.
- Вы можете создать промежуточное программное обеспечение, такое как принтер журнала, для регистрации действия каждый раз, когда пользователь отправляет действие, и вам будет легче отлаживать и исправлять ошибки, когда что-то пойдет не так.
- Обязательно управление всеми действиями через магазин, чтобы командная разработка была более удобной и понятной
Суммировать
Посредством долгосрочного анализа мы можем сделать вывод этой статьи.
- Vuex официально запущен, и шина событий является мастером в народном
- vuex действительно лучше, чем EventBus, для больших приложений.
- vuex легче отлаживать и управлять
- Vuex — не лучшее решение, в некоторых небольших приложениях у вас может быть только небольшая часть взаимодействия с данными или даже только хранилище состояния входа, такое как шина событий илиПростое управление состояниемВсе рекомендуют.
В конце концов, vuex действительно ароматный. ps: Это всего лишь мнение автора, если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь вносить исправления. 😘