我仍然认为您应该重组您的组件,以便将数据加载到视图组件中而不是存储中。存储用于在不同视图之间共享的数据,或者至少与应用程序的更广泛部分相关,而您的数据似乎只特定于一个视图。只需通过 props 传递数据即可。
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)之类的方式发送加载操作
如果您选择使用组件名称的方式,您将必须按照上面的说明进行提交。否则,您可以简单地使用 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 });
}
}
}