具有相同Vuex存储的多个Vue.js组件

时间:2019-10-08 19:35:32

标签: vue.js vuex

在组件1中,一些数据正在使用异步方法加载并存储在Vuex存储中。其他组件2正在使用同一存储,并且当用户从组件1导航到组件2时必须清除数据。

下面是正常的工作流程,工作正常。

  1. 组件1-加载数据已完成(异步,等待)
  2. 用户导航到组件2
  3. 在停用事件中清除了组件1的数据
  4. 组件2正常显示

现在,当用户打开组件1并快速导航到组件2时。

  1. 组件1-已启动数据请求,但尚未加载数据
  2. 用户导航到组件2
  3. 在停用事件中清除了组件1的数据
  4. 组件1异步操作已完成,数据现在已加载到状态
  5. 组件2将显示用于组件1的数据

2 个答案:

答案 0 :(得分:1)

我仍然认为您应该重组组件,以便将数据加载到视图组件中而不是存储中。存储用于存储在不同视图之间共享的数据,或者至少与应用程序的更广泛部分相关的数据,而您的数据似乎仅特定于一个视图。只需通过道具传递数据即可。

Views
- View A
- View B
Components
  Common
    - Sidebar (the common sidebar that is loaded in both View A and View B)
  - Some other components specific to view a and b

如果您打算继续使用商店存储本地数据,我认为您有多种选择:

  • 您可以使用URL或视图名称来键入加载程序。在您的状态下,通常只要有数据,现在就有一个将路线或视图名称映射到某些数据的对象。然后,您使用一个自动获取器的吸气剂。这样做的另一个好处是,您可以根据需要保留数据,这样可以在返回该视图时加快加载速度(不再需要进行api调用)。
  • 您向存储库提交了一些令牌,并且仅在令牌与检索令牌匹配时才覆盖存储状态下的数据。 (例如,dispatch('get/my/data', { token: 'asdf' })之前是commit('switch/to/view', 'asdf')。如果该视图与我们当前所在的视图不匹配,我们将直接丢弃数据。

在两种情况下,您都将使用类似dispatch('get/my/data', { view: this.$options.name })(或:this.$route.paththis.$route.name)的内容来调度加载操作

如果遵循使用组件名称的方法,则必须像上面概述的那样进行提交。否则,您可以简单地使用import router from '../router'或类似名称导入路由器。

对于第一个选项,您将获得以下内容:

从“ ../router”导入路由器; 从“ vue”导入Vue;

{
  state: {
    data: {},
  },
  getters: {
    getData (state) {
      return state.data[router.currentRoute.path];
    }
  },
  mutations: {
    setData (state, { view, data }) {
      Vue.$set(state.data, view, data);
    }
  },
  actions: {
    async fetchData ({ commit }, { view }) {
      const data = await myApiPromise;

      commit('setData', { view, data });
    }
  }
}

现在,getData返回数据(如果已为该视图加载数据),或者返回undefined(如果尚未加载数据)。切换将仅获取先前存储的数据,这可能对您或有用。

第二个选项是相似的,但是您还有其他需要担心的变化。在每个视图中都从created调用该突变。不用担心在销毁组件时会自己清理,而只是在进行提取之前清理。

{
  state: {
    data: null,
    view: '',
  },
  getters: {
    getData (state) {
      return state.data[router.currentRoute.path];
    }
  },
  mutations: {
    clearData (state) {
      Vue.$set(state, 'data', null);
    },
    setData (state, { view, data }) {
      if (state.view !== view) {
        // Do not update
        return;
      }

      Vue.$set(state, 'data', data);
    },

    setView (state, { view }) {
      Vue.$set(state, 'view', view);
    }
  },
  actions: {
    async fetchData ({ commit }, { view }) {
      commit('clearData');
      const data = await myApiPromise;

      commit('setData', { view, data });
    }
  }
}

答案 1 :(得分:-1)

当用户从组件1导航到组件2时,在Vue生命周期中使用销毁的回调来清除商店

Aource:https://vuejs.org/v2/api/#destroyed

您仍然可以添加状态以检查用户当前的导航页面,并在商店突变中设置标记以更新状态,仅用户处于预期的组件中,否则就忽略