3 回答
TA贡献1884条经验 获得超4个赞
这样做的方法是存储状态值。
例如,如果您的商店依赖于单个 API,您将执行以下操作。但是,对于多个 API,最好单独存储每个 api 加载状态,或者为每个 API 使用一个专用对象。
通常你可以拥有 4 种状态,我更喜欢在全局可访问模块中拥有它们:
// enums.js
export default {
INIT: 0,
LOADING: 1,
ERROR: 2,
LOADED: 3
};
然后,您可以将变量存储在 vuex 状态中,其中 apiState 使用INIT. 您也可以使用 初始化数组[],但这不是必需的。
import ENUM from "@/enums";
// store.js
export default new Vuex.Store({
state: {
apiState: ENUM.INIT,
accounts: [],
// ...other state
},
mutations: {
updateAccounts (state, accounts) {
state.accounts = accounts;
state.apiState = ENUM.LOADED;
},
setApiState (state, apiState) {
state.apiState = apiState;
},
},
actions: {
loadAccounts ({commit) {
commit('setApiState', ENUM.ERROR);
somFetchInterface()
.then(data=>commit('updateAccounts', data))
.catch(err=>commit('setApiState', ENUM.ERROR))
}
}
});
然后,通过添加一些computeds,您可以切换显示哪个组件。这显示了使用状态的好处,因为您可以轻松识别错误状态,并在状态未准备好时显示加载动画。
<template>
<ChildComponent v-if="apiStateLoaded"/>
<Loader v-if="apiStateLoading"/>
<Error v-if="apiStateError"/>
</template>
<script>
import ENUM from "@/enums";
export default {
computed: {
...mapState({
apiState: state=> state.apiState
}),
apiStateLoaded() {
return this.apiState === ENUM.LOADED;
},
apiStateLoading() {
return this.apiState === ENUM.LOADING || this.apiState === ENUM.INIT;
},
apiStateError() {
return this.apiState === ENUM.ERROR;
},
})
}
</script>
或者,如果您只是asyncListValues使用空数组在 store 中初始化[],则可以避免期望数组的错误。
TA贡献1993条经验 获得超5个赞
由于您vue-router在问题中提到过,您可以使用beforeRouteEnterwhich 来推迟组件的渲染。
例如,如果您有一条名为“photo”的路线:
import Photo from "../page/Photo.vue";
new VueRouter({
mode: "history",
routes: [
{ name: "home", path: "/", component: Home },
{ name: "photo", path: "/photo", component: Photo }
]
});
你可以这样使用beforeRouteEnter:
<template>
<div>
Photo rendered here
</div>
</template>
<script>
export default {
beforeRouteEnter: async function(to, from, next) {
try {
await this.$store.dispatch("longRuningHttpCall");
next();
} catch(exception) {
next(exception);
}
}
}
</script>
它的作用是,等待操作完成,根据需要更新您的状态,然后调用next()将告诉路由器继续该过程(在 中渲染组件<router-view></router-view>)。
告诉我您是否需要 ES6-less 示例(例如,如果您不使用此语法)。
您可以查看此页面上的官方文档beforeRouteEnter,您还会发现您也可以使用beforeEnter.
TA贡献1801条经验 获得超16个赞
一种方法是将您的组件拆分为两个不同的组件。一旦数据准备好,您的新父组件可以处理获取数据并呈现子组件。
父组件.vue
<template>
<child-component v-if="asyncListValues && asyncListValues.length" :asyncListValues="asyncListValues"/>
<div v-else>Placeholder</div>
</template>
<script>
export default {
computed: {
...mapState({
asyncListValues: state => state.asyncListValues
})
}
}
</script>
子组件.vue
export default {
props: ["asyncListValues"],
mounted () {
this.asyncListValues.forEach((val) => {
// do stuff
});
}
}
添加回答
举报