【发布时间】:2022-01-06 18:10:13
【问题描述】:
请告诉我我对使用 Vuex 还是很陌生,还不太了解它。 我正在为 IndexedDB 使用带有 localforage 包的 Vuex4。
我的Vuex商店如下:
import { createStore } from 'vuex'
import localforage from 'localforage'
import axios from 'axios'
const store = createStore({
state: {
tenantLocale: {}
},
getters: {},
mutations: {
setLocale(state, value) {
state.tenantLocale = value
}
},
actions: {
getTenant(context) {
axios.get('/api/tenant-data/locale').then((response) => {
context.commit('setLocale', response.data)
localforage.setItem('tenantLocale', response.data)
})
}
}
})
export default store
我像这样在我的 App.vue 中调度操作:
import { useStore } from 'vuex'
export default {
setup() {
const store = useStore()
//get default information about tenant from api
store.dispatch('getTenant')
return {}
}
}
现在的问题是,如果我在模板部分的 Login.vue 组件中呈现状态,如下所示:
<h1>{{ store.state.tenantLocale.timezone }}</h1>
它显示了正确的数据,但是如果我尝试在我的组件的脚本部分对它做一些事情,比如说尝试打印出来:
console.log(store.state.tenantLocale.timezone)
我收到未定义的消息。
我在这里缺少什么?这里最好的方法是什么?我需要为它创建吸气剂吗?创建一个承诺?我的大脑被炸了......任何帮助至少将我指向正确的方向表示感谢!
【问题讨论】:
-
“但是如果我尝试在我的组件的脚本部分用它做一些事情” - 究竟在哪里?该操作是异步的。您无法同步获得结果。将异步副作用仅放入 setup 是错误的,应该在 onMounted 内部,或者整个组件需要异步。
-
我明白你的意思,但我试着把它放在 onMounted 里面我仍然得到未定义的结果,这就是我这么困惑的原因
-
您在 onMounted 中究竟做了什么?在异步操作完成之前,您不能期望它被定义。如果它是通过 getTenant 操作完成的,那么通常你必须等待一个承诺。 “创建一个承诺?” - 已经有一个来自
dispatch的承诺,你忽略了它。如果您不确定那里发生了什么,您也可以查看stackoverflow.com/questions/14220321/… -
例如,如果我想创建一个基于tenantLocale 对象取值的日期:
date = new Date().toLocaleString(store.state.tenantLocale.localization, { timeZone: `${store.state.tenantLocale.timezone}` }) -
正如答案所暗示的,
date应该是一个计算值。如果在您访问date时该值未定义,这意味着您需要以某种方式推迟其访问,直到所有相关数据都可用。在 Vue 中有几种统一的方法可以做到这一点。这取决于您的情况,哪个更可取。您可以将 dispatch('getTenant') 移动到父级并且在数据可用之前不渲染子级,或者使用 Vue 3 的 Suspense
标签: javascript vue.js vuex vuejs3 vuex4