Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有相同Vuex存储的多个Vue.js组件_Vue.js_Vuex - Fatal编程技术网

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

具有相同Vuex存储的多个Vue.js组件,vue.js,vuex,Vue.js,Vuex,在组件1中,有一些数据使用异步方法加载并存储在Vuex存储中。其他组件2正在使用同一存储,当用户从组件1导航到组件2时,必须清除数据 以下是正常的工作流程,工作正常 组件1-加载数据完成(异步、等待) 用户导航到组件2 组件1数据在停用事件中被清除 组件2显示良好 现在,当用户打开组件1并快速导航到组件2时 组件1-数据请求已启动,但尚未加载数据 用户导航到组件2 组件1数据在停用事件中被清除 组件1异步操作已完成,数据现在已加载到状态 组件2将显示组件1的数据 当用户从组件1导航到组件2时,在

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

以下是正常的工作流程,工作正常

  • 组件1-加载数据完成(异步、等待)
  • 用户导航到组件2
  • 组件1数据在停用事件中被清除
  • 组件2显示良好
  • 现在,当用户打开组件1并快速导航到组件2时

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

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

    A来源:


    您仍然可以添加一个状态来检查用户当前的导航页面,并在存储区中设置一个标志,以更新状态“仅用户在预期组件中”,否则只需忽略当用户从组件1导航到组件2时,使用Vue生命周期中的已销毁回调清除存储区

    A来源:


    您仍然可以添加一个状态来检查用户当前的导航页面,并在存储区中设置一个标志,以更新状态“仅用户在预期组件中”,否则请忽略我仍然认为您应该重新构造组件,使其在视图组件而不是存储区中加载数据。存储区用于在不同视图之间共享的数据,或至少与应用程序的更广泛部分相关的数据,而您的数据似乎只特定于一个视图。只需通过道具传递数据即可

    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或视图名称为加载程序设置键。在您的状态中,您通常只会有数据,现在您有了一个将路由或视图名称映射到某些数据的对象。然后使用一个getter自动为您获取正确的数据。这样做的另一个好处是,如果愿意,您可以将数据保留在视图中,这样可以在返回到该视图时加快加载速度(不再需要进行api调用)
    • 您向存储提交一些令牌,并且仅当令牌与检索令牌匹配时才覆盖存储状态中的数据。(例如,
      dispatch('get/my/data',{token:'asdf'})
      之前执行
      commit('switch/to/view','asdf')
      时。如果视图与我们当前所在的视图不匹配,我们只需丢弃数据即可
    在这两种情况下,您都会使用类似于
    dispatch('get/my/data',{view:this.$options.name})
    (或:
    this.$route.path
    this.$route.name
    )的内容来分派加载操作

    如果使用组件名称,则必须按照上述方式进行提交。否则,只需使用“../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
    。切换只需获取以前存储的数据,这可能对您有用,也可能对您有用

    第二个选项与此类似,但您需要担心一个额外的变异。该变异是从每个视图中创建的
    调用的。销毁组件时不要担心自己清理,而是在执行提取之前进行清理

    {
      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 });
        }
      }
    }
    

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

    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或视图名称为加载程序设置关键帧。在您的状态下,您通常只需要数据,现在您有了一个将路由或视图名称映射到某些数据的对象。然后,您可以使用getter自动为您获取正确的数据。这样做的附加好处是,如果愿意,您可以将数据保留在其中当您返回到该视图时,可以加快加载速度(不再需要执行api调用)
    • 您向存储提交一些令牌,并且仅当令牌与检索令牌匹配时才覆盖存储状态中的数据。(例如,
      dispatch('get/my/data',{token:'asdf'})
      而之前执行
      commit('switch/to/view','asdf'))
      。如果视图与我们当前所在的视图不匹配,我们只需丢弃数据即可
    在这两种情况下,您都会使用类似于
    dispatch('get/my/data',{view:this.$options.name})
    (或:
    this.$route.path
    this.$route.name
    )的内容来分派加载操作

    如果使用组件名称,则必须按照上述方式进行提交。否则,只需使用“../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
    。切换只需获取以前存储的数据,这可能对您有用,也可能对您有用

    第二个选项是类似的,但您有一个额外的变种