javascript - 从持久存储重新水化后,Vuex getter 不会更新
问题描述
我的 Electron + Vue 设置遇到了一个奇怪的问题。
条件: Electron + Vue(我使用了样板文件)+ vuex-persist(也尝试了 vuex-persistedstate和vuex-persistfile)。
问题: Vuex getter 在 store 被补水时保持 0/null/''。我怎么知道?如果本地存储是干净的(我第一次启动应用程序),第一个突变更新状态(getter 返回正确的值),我可以看到一个对象被添加到浏览器的本地存储中。但是,当应用程序重新启动时,突变会像以前一样触发状态和本地存储更新,但getter 保持为空/默认。下面的 getter 返回一个空数组。
设置:我有一个与 3rd 方 API 配合使用的应用程序:获取数据、计算内容并将一些数据发回。API 也需要授权。下面是我的 Vuex 结构。
我的状态对象的一部分...
const state = {
token: '',
projects: [],
work_packages: [],
timeEntriesLocal: []
}
...和我的一个吸气剂:
const getters = {
todayLog () {
function sameDay (d1, d2) {
return d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate()
}
var entries = state.timeEntriesLocal
var todayEntries = []
entries.forEach(element => {
var date = element.spentOn
var today = new Date()
if (sameDay(date, today)) {
todayEntries.push(element)
}
})
return todayEntries
}
}
它从数组中返回由于“今天”而产生的条目。
timeEntriesLocal 填充了这个方法:
addTimeEntry () {
let entry = {
id: this.$store.state.UserData.timeEntriesLocal.length + 1,
project: this.getItemById(this.$store.state.UserData.current.project_id, this.$store.state.UserData.projects),
spentOn: new Date(),
comment: this.comment,
activityId: this.activityId,
workPackage: this.getItemById(this.$store.state.UserData.current.work_package_id, this.$store.state.UserData.work_packages),
hours: this.precisionRound(this.$store.state.UserData.duration / 60 / 60, 2),
published: false,
loading: false,
infoMessage: ''
}
this.$store.commit('ADD_LOCAL_ENTRY', entry)
}
最后是我刚刚在上面使用的突变:
ADD_LOCAL_ENTRY (state, entry) {
state.timeEntriesLocal.unshift(entry)
}
解决方案
由于您正在更改timeEntriesLocal
Array 的长度,因此未获取更改。这是文档的Common Gotchas部分中涵盖的 JavaScript 限制。Vuex 的文档中还介绍了一种解决方法:
突变遵循 Vue 的反应规则
由于 Vuex 存储的状态是由 Vue 做出的反应,所以当我们改变状态时,观察状态的 Vue 组件会自动更新。这也意味着 Vuex 突变在使用普通 Vue 时会受到相同的反应性警告:
- 更喜欢预先使用所有所需字段初始化商店的初始状态。
向对象添加新属性时,您应该:
Use Vue.set(obj, 'newProp', 123)
, 或者- 用一个新的对象替换那个对象。例如,使用对象扩展语法,我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }
因此,在您的示例中,要让 Vue (Vuex) 检测到这些更改,您可以执行以下操作:
ADD_LOCAL_ENTRY (state, entry) {
state.timeEntriesLocal.unshift(entry);
Vue.set(state, 'timeEntriesLocal', state.timeEntriesLocal);
}
推荐阅读
- python - Pandas - 散点图 - cmap 标签的旋转
- vb.net - 提取和覆盖 .zip 文件 (.NET Framework 4.7.2.)
- python - SQLAlchemy - DetachedInstanceError 父实例未绑定到会话
- scala - 需要帮助从 Spark 2.0 迁移到 Spark 3.1 - 可累加到 AccumulatorV2
- python - 在 for 循环中更改 csv 文件的索引列名称
- javascript - 用不同的代码替换 MicrosoftAjax.js 文件中的 eval()
- java - Thread.Interrupt() 不起作用,我真的不明白为什么
- android - Jacoco Gradle Plugin:如何从子模块生成检测的 jar 文件?
- python - 在 python 后端业务逻辑中,我如何以及在哪个模块中引用 Django 用户上传的文件?
- reactjs - TypeError:不是子组件中的函数错误