EventBus & Vuex?

Vuex

Несколько дней назад друг спросил в группе, что 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
В начале наш проект может быть таким простым, как этот

Спустя долгое время королевство продолжало расти, проект становился все больше и больше, компонентов в башне компонентов становилось все больше и больше, и они становились все более и более сложными, все королевство превращалось в беспорядок, а структура проекта стал следующий вид. Коммуникаций между разными компонентами становится все больше и постоянное появление $emit и $on в сегменте кода приводит к следующим основным проблемам

1. 代码逻辑性极具下降,可阅读性变低
2. 对于每一个action父组件都需要一个on(或dispatch)一个事件来处理
3. 你将很难查找到每一个事件是从哪里触发,满篇都是业务逻辑

простой пример

Возьмем простой пример. В вашей компании изначально был компонент отображения, и его роль заключалась в отображении текущего значения приращения в корневом компоненте приложения. Вы нанимаете двух новых сотрудников и назначаете им две задачи.

  1. Вы позволяете Xiao A разработать новый счетчик и использовать его в новом компоненте (childDisplay), понимаете, что один щелчок увеличивает приращение один раз, и отображаете текущее количество приращений в компоненте. Этот счетчик подписан на увеличение, и щелчок по счетчику приводит к тому, что display и childDisplay отображают увеличенное число на 1.
    Сяо А с радостью и быстро выполнил фиксацию задачи, а затем нажал
  2. Вы сказали Xiao B, что мне нужен компонент кнопки, этот компонент кнопки генерирует событие сброса для экземпляра приложения, это событие сбрасывает приращение в приложении до 0
    Ладно, малыш Б тоже с радостью совершает и пушит
  3. В это время вы обнаружите, что когда вы нажимаете на компонент A, число после приращения успешно отображается как на дисплее, так и на childDiplay, но когда вы нажимаете на компонент B, чтобы вызвать событие сброса, приращение на корневом компоненте равно сбрасывается на 0, но из-за малого B не знает, что компонент A также подписывается на данные приращения, в результате чего состояние компонента A не обновляется.

vuex

Чтобы предотвратить эти проблемы, в это время встал король Ю Сяою.С помощью мыслей соседнего Королевства Потоков он повел мудрецов по всей стране изучать новый способ решения этой хаотичной проблемы. Это векс.

По определению

  1. store — это склад, на складе хранятся данные проекта (store.state)
  2. (Строгий режим) Чтобы решить проблему невозможности отслеживания изменений состояния, данные в хранилище не изменяются напрямую путем изменения store.state, а передаются в хранилище через действие фиксации, и будет сообщено об ошибке.[vuex] Do not mutate vuex store state outside mutation handlers
  3. После того, как хранилище получит действие фиксации, оно найдет соответствующее событие в store.mutation и изменит store.state.

Вернемся к простому примеру

Решение 1 (Простой режим магазина)

Чтобы решить вышеуказанные проблемы, мы внесли несколько интересных изменений. (состояние)

  1. Определить постоянное хранилище в хранилище
  2. Переменная с именем sharedState определена в локальных данных, которые являются отображением в store.state.
  3. Поскольку 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 медленно обретает форму.

vuex
Мы воссоздаем store.js

import 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

Давайте посмотрим, что здесь происходит

  1. Мы представили модуль vuex и активировали его как плагин vue.
  2. Наш склад-хранилище больше не является обычным jsonObject, а является экземпляром vuex.store.
  3. Использование мутации для изменения состояния

why better ?

  1. Если мы сохраняем копии всех состояний во время разработки, мы можем отлаживать код как супергерой во времени и пространстве, записывая каждое изменение состояния.
  2. Вы можете создать промежуточное программное обеспечение, такое как принтер журнала, для регистрации действия каждый раз, когда пользователь отправляет действие, и вам будет легче отлаживать и исправлять ошибки, когда что-то пойдет не так.
  3. Обязательно управление всеми действиями через магазин, чтобы командная разработка была более удобной и понятной

Суммировать

Посредством долгосрочного анализа мы можем сделать вывод этой статьи.

  1. Vuex официально запущен, и шина событий является мастером в народном
  2. vuex действительно лучше, чем EventBus, для больших приложений.
  3. vuex легче отлаживать и управлять
  4. Vuex — не лучшее решение, в некоторых небольших приложениях у вас может быть только небольшая часть взаимодействия с данными или даже только хранилище состояния входа, такое как шина событий илиПростое управление состояниемВсе рекомендуют.
    В конце концов, vuex действительно ароматный. ps: Это всего лишь мнение автора, если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь вносить исправления. 😘