Как мгновенно обновить изменения, внесенные в хранилище vuex, в пользовательском интерфейсе другого компонента?

#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. Я пропустил это, чтобы ввести… В реальном приложении оно возвращается… это просто ошибка при переполнении стека …. внутри моего компонента приложения он возвращается … извините.. Но проблема не в этом ..!