Я уже довольно давно использую шину глобальных событий в Vue - что-то вроде const bus = new Vue()
.Работает нормально, однако, удаление подписок может стать довольно многословным.
Допустим, я подписываюсь на событие в компоненте:
mounted() {
bus.$on('some.event', callback)
}
Я должен был бы отслеживать обратный вызов иутилизируйте его правильно в beforeDestroy
.Это можно несколько упростить, используя глобальный миксин, но, поскольку я использую <keep-alive>
, я должен различать подписки, сделанные с помощью обратного вызова mounted
и activated
.
Так что я решил дать Vuexвыстрел в управлении этим, так как наблюдатели располагаются рамками.Я пришел с предложением ниже.
Кажется, работает нормально, пока публикуются объекты или массивы.Кажется, что примитивные данные не вызывают реактивность, несмотря на то, что они обернуты во внешний объект, то есть { data: 123 }
Я ищу альтернативные решения в отношении уведомления подписчиков.Все, что я видел до сих пор, это внутренний метод notify
, который не очень безопасен в использовании.
eventstore.js
import Vue from 'vue'
const state = {
events: {}
}
const actions = {
publish({commit}, payload) {
commit('publish_event', payload)
}
}
const mutations = {
publish_event(state, payload) {
if(!state.events[payload.key]) {
Vue.set(state.events, payload.key, { data: payload.data })
} else {
state.events[payload.key] = { data: payload.data }
}
}
}
const getters = {
events: state => state.events
}
export default {
state,
actions,
mutations,
getters
}
globalmixin.js
methods: {
publish(key, data) {
this.$store.dispatch('publish', { key, data })
}
}
somecomponent.vue
function mapEventGetters(eventKeys) {
return _.reduce(eventKeys, (result, current) => {
result[current] = function() {
return _.get(this, `$store.getters.events.${current}.data`)
}
return result
}, {})
}
computed: {
...mapEventGetters(['foo_bar'])
},
watch: {
'foo_bar'(value) {
console.log(`foo_bar changed to ${value}`)
}
}