在 VueRouter beforeEach 中使用 promised getter
Use promised getter in VueRouter beforeEach
我一直在努力使用从 vuex.actions
计算得出的 vuex.getters
作为 router.beforeEach
中的 if
语句。
这是我正在尝试做的事情:
每次用户进入网站时获取一组对象。
然后根据router.params.id
使用array.find()
定位同一个对象,以防用户直接进入站点url。
如果 router.params.id
不匹配对象数组中的任何 slug,则将路由重定向到 404。
这是我的方法
const router = new VueRouter(
{
routes: [
{
path: '/list/:id',
name: 'list'
},
{
path: '/edit/:id',
name: 'edit'
},
//other routes
{
path: '/*',
name: '404'
}
]
}
);
router.beforeEach((to, from, next)=>{
if ( !store.state.lists.length ){
// fetch Object Array when user first enter
store.dispatch('fetchLists');
}
if ( to.name === 'list' || to.name === 'edit'){
// limit route only 'list' & 'edit', preventing passing undefined params
store.commit('cloneParams', to);
// determine if currentMonth has a valid slug, if not go to 404
store.getters.currentMonth.slug !== '' ? next() : next('/404');
} else {
next();
}
});
getters: {
currentMonth(state){
var template = {
month: '',
slug: '',
data: []
}
var obj = template;
if ( state.lists.length ) {
obj = state.lists.find(current => current.slug === state.paramsID);
if ( obj === undefined ){
obj = template
}
}
return obj;
},
actions: {
fetchLists({commit}){
axios('/lists').then(
res=>{
commit('storeList', res);
}
)
},
mutations: {
storeList(state, res){
state.lists = res.data;
},
cloneParams(state, to){
state.paramsID = to.params.id;
},
但是,我发现 getter currentMonth
在获取对象数组 store.state.lists
并转到 404 后没有更新。同时它在 [=24 之后工作得很好=] 在用户转到此 SPA 的下一个其他页面时获取并存储。
路由守卫在检查 api 结果之前没有等待 http 请求完成。 Return 来自 fetchLists
的承诺:
actions: {
fetchLists({commit}){
return axios('/lists').then(res => { // return the promise
commit('storeList', res);
})
},
然后在导航守卫中等待那个承诺:
router.beforeEach(async (to, from, next) => { // async keyword
if ( !store.state.lists.length ){
await store.dispatch('fetchLists'); // Waiting for the promise
}
if ( to.name === 'list' || to.name === 'edit'){
// limit route only 'list' & 'edit', preventing passing undefined params
store.commit('cloneParams', to);
// determine if currentMonth has a valid slug, if not go to 404
store.getters.currentMonth.slug !== '' ? next() : next('/404');
} else {
next();
}
});
我一直在努力使用从 vuex.actions
计算得出的 vuex.getters
作为 router.beforeEach
中的 if
语句。
这是我正在尝试做的事情:
每次用户进入网站时获取一组对象。
然后根据
router.params.id
使用array.find()
定位同一个对象,以防用户直接进入站点url。如果
router.params.id
不匹配对象数组中的任何 slug,则将路由重定向到 404。
这是我的方法
const router = new VueRouter(
{
routes: [
{
path: '/list/:id',
name: 'list'
},
{
path: '/edit/:id',
name: 'edit'
},
//other routes
{
path: '/*',
name: '404'
}
]
}
);
router.beforeEach((to, from, next)=>{
if ( !store.state.lists.length ){
// fetch Object Array when user first enter
store.dispatch('fetchLists');
}
if ( to.name === 'list' || to.name === 'edit'){
// limit route only 'list' & 'edit', preventing passing undefined params
store.commit('cloneParams', to);
// determine if currentMonth has a valid slug, if not go to 404
store.getters.currentMonth.slug !== '' ? next() : next('/404');
} else {
next();
}
});
getters: {
currentMonth(state){
var template = {
month: '',
slug: '',
data: []
}
var obj = template;
if ( state.lists.length ) {
obj = state.lists.find(current => current.slug === state.paramsID);
if ( obj === undefined ){
obj = template
}
}
return obj;
},
actions: {
fetchLists({commit}){
axios('/lists').then(
res=>{
commit('storeList', res);
}
)
},
mutations: {
storeList(state, res){
state.lists = res.data;
},
cloneParams(state, to){
state.paramsID = to.params.id;
},
但是,我发现 getter currentMonth
在获取对象数组 store.state.lists
并转到 404 后没有更新。同时它在 [=24 之后工作得很好=] 在用户转到此 SPA 的下一个其他页面时获取并存储。
路由守卫在检查 api 结果之前没有等待 http 请求完成。 Return 来自 fetchLists
的承诺:
actions: {
fetchLists({commit}){
return axios('/lists').then(res => { // return the promise
commit('storeList', res);
})
},
然后在导航守卫中等待那个承诺:
router.beforeEach(async (to, from, next) => { // async keyword
if ( !store.state.lists.length ){
await store.dispatch('fetchLists'); // Waiting for the promise
}
if ( to.name === 'list' || to.name === 'edit'){
// limit route only 'list' & 'edit', preventing passing undefined params
store.commit('cloneParams', to);
// determine if currentMonth has a valid slug, if not go to 404
store.getters.currentMonth.slug !== '' ? next() : next('/404');
} else {
next();
}
});