javascript - 在加载组件之前等待 VueX 值加载
问题描述
当用户尝试直接导航加载组件 url 时,会在我的 vuex 操作中进行 http 调用,一旦它解析,它将在我的状态中定义一个值。
我不想加载我的组件,直到 http 调用被解决,并且状态值被定义。
例如,在我的组件中
export default {
computed: {
...mapState({
// ** this value needs to load before component mounted() runs **
asyncListValues: state => state.asyncListValues
})
},
mounted () {
// ** I need asyncListValues to be defined before this runs **
this.asyncListValues.forEach((val) => {
// do stuff
});
}
}
在加载我的组件之前,如何让我的组件等待asyncListValues
加载?
解决方案
一种方法是存储状态值。
例如,如果您的商店依赖于单个 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.LOADING);
someFetchInterface()
.then(data=>commit('updateAccounts', data))
.catch(err=>commit('setApiState', ENUM.ERROR))
}
}
});
然后,通过添加一些computed
变量,您可以切换显示哪个组件。使用状态的好处是可以轻松识别错误状态,并在状态未就绪时显示加载动画。
<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>
除了......我使用这种模式来管理我的应用程序作为状态机。虽然这个例子使用了 vuex,但它可以适应在组件中使用,使用Vue.observable
(vue2.6+) 或ref
(vue3)。
或者,如果你只是asyncListValues
用一个空数组初始化你的存储[]
,你可以避免期望数组的错误。
推荐阅读
- python - 在 Python 中仅从 lru_cache 中弹出一项
- javascript - 通过检索指定的会话存储项清除会话存储数据
- azure-devops - 管道 -> 运行 -> 运行管道如何在请求正文中提供管道资源
- visual-studio-code - VSCode - 如何删除命令面板中的特定命令历史记录(而不是清除所有内容)?
- sql - SQL 按子网排序,然后按名称排序
- apache-kafka - Kafka将打开文件的数量减少为超过1000000
- android - 如何使用 Kotlin 在内部创建接口方法?
- mysql - .env 文件中数据库连接的 Atom 编辑器出错。当我导入 Laravel-8 项目时,Atom 无法识别某些文件
- javascript - 从任意和深度嵌套的 JSON(带数组)中过滤属性的通用方法
- emscripten - Emscripten:如何从 16 MB 增加堆内存