#javascript #vue.js #vuejs2
#javascript #vue.js #vuejs2
Вопрос:
Как мгновенно обновить изменения, внесенные в хранилище vuex, в пользовательском интерфейсе другого компонента?
ниже приведен модуль хранилища vuex компонента
const { property } = require("lodash")
export default {
state: {
data: [
{id: 1, name: 'Angular', status: 'active'},
{id: 2, name: 'React', status: 'active'},
{id: 3, name: 'Vue', status: 'inactive'},
]
},
mutations: {
UPDATE_ITEM(state, payload) {
const item = state.data.find(item => _.isEqual(item, payload.item))
Object.assign(item, payload.status);
},
},
actions: {
updateItem({ commit }, payload) {
commit("UPDATE_ITEM", payload);
},
},
getters: {
getData: (state) => state.data,
getMappedStatus: (state) => state.data.map(data => data.status)
},
};
вот как я получаю отображенный статус в компоненте 1
computed: {
getMappedStatus() {
return this.$store.geters.getMappedStatus
}
}
и внутри пользовательского интерфейса компонента 1
<ul>
<li v-for="item in getMappedStatus>{{item}} </li>
</ul>
из другого компонента 2 я обновляю изменения по мере ввода пользователем статуса:
onStatusChanges(item, status) {
this.$store.dispatch("updateItem", {
item, status
});
},
Но проблема в том, что, хотя состояние обновляется, пользовательский интерфейс не обновляется. Но
(внутри компонента 1)
Я думаю, это из-за вычисляемого свойства. … не уверен.
Как я могу реализовать что-то вроде и наблюдаемое или что-то реактивное, чтобы вычисляемое свойство getMappedStatus в компоненте 1 обновлялось автоматически при отправке действия из компонента 2.
Обратите внимание, что оба компонента входят в один и тот же модуль хранилища vuex
Если бы это было в angular / ngrx, я бы подписался на селекторы внутри компонента 1, и я бы мгновенно получил изменения. даже если я подпишусь на событие внутри метода OnInit() или constructor() и выполню console.log(), изменения из другого компонента будут отражены мгновенно.
Но этого не происходит с vuex.
Как я могу этого добиться:?
или есть способ инициировать обновление вычисляемого свойства getMappedStatus внутри компонента 1, как только происходят изменения из компонента 2:
computed: {
getMappedStatus() {
return this.$store.geters.getMappedStatus
}
}
таким образом, пользовательский интерфейс компонента 1 обновляется мгновенно.
Комментарии:
1.
updateItem
действие возвращает a<promise>
. Зафиксируйте мутацию в хранилище vuex вthen
блоке. а затем используйте computed в любом компоненте, который вы хотите.2. Да. Но updateItem — это действие, отправляемое из другого компонента. Но мне нужно, чтобы изменения отражались в другом компоненте с помощью геттеров.
Ответ №1:
Мы можем думать о getters
вычисляемых свойствах для хранилищ. Как и вычисляемые свойства, результат getter кэшируется на основе его зависимостей и будет повторно оцениваться только тогда, когда некоторые из его зависимостей изменились, так что это просто означает, что если component1
изменяет состояние в vuex
хранилище и component2
использует это свойство из хранилища, оно автоматически обновляется во всех компонентах, использующих его.
Онлайн-среда разработки — живая демонстрация здесь
Хранилище Vuex
const store = new Vuex.Store({
state: {
name: 'mex'
},
mutations: {
mutateName(state, value) {
state.name = value;
}
},
actions: {
updateName(context, payload) {
context.commit('mutateName', payload.name);
}
},
getters: {
getName(state) {
return state.name;
}
}
});
changeName
Метод при запуске отправляет updateName
действие, которое обновит имя, и все компоненты будут соответствующим образом обновляться, потому что оно реагирует.
Затем в любом компоненте
computed:{
name() {
return this.$store.getters.getName
}
},
methods: {
changeName: function () {
this.$store.dispatch('updateName', { name: 'mexxxxx'});
}
}
Комментарии:
1. Я пропустил это, чтобы ввести… В реальном приложении оно возвращается… это просто ошибка при переполнении стека …. внутри моего компонента приложения он возвращается … извините.. Но проблема не в этом ..!
Ответ №2:
Вам нужно вернуть что-то из getMappedStatus
computed: {
getMappedStatus() {
return this.$store.geters.getMappedStatus
}
}
… без return
оператора this.$store.geters.getMappedStatus
это просто выражение, и ваше вычисляемое свойство всегда возвращается undefined
(потому что JS функционирует без return
always return undefined
)
Комментарии:
1. Я пропустил это, чтобы ввести… В реальном приложении оно возвращается… это просто ошибка при переполнении стека …. внутри моего компонента приложения он возвращается … извините.. Но проблема не в этом ..!