Vuex 动作中的顺序依赖函数
Sequential dependent functions in Vuex action
我目前正在构建一个 Vue 应用程序,它使用 Contentful API 中的数据。对于每个条目,我都有一个 thumbnail
(图像)字段,我想从中提取突出的颜色作为十六进制值,并将它们存储在应用程序其他地方使用的状态。
使用 Vuex 操作 (getAllProjects) 查询 API、运行 Vibrant (node-vibrant) 并将响应提交到状态。
async getAllProjects({ commit }) {
let {
fields: { order: order }
} = await api.getEntry("entry");
let projects = order;
projects.forEach(p =>
Vibrant.from(`https:${p.fields.thumbnail.fields.file.url}`)
.getPalette()
.then(palette => (p.fields.accent = palette.Vibrant.hex))
);
console.log(projects);
// Commit to state
commit("setAllProjects", projects);
}
当我在调用 commmit
之前记录 projects
的内容时,我可以看到我在 之后添加的十六进制值是 accent
键。但是,当我在 devtools 中检查突变有效载荷时,accent
键丢失了,因此最终没有进入状态。
我如何构建这些任务,以便 commit
仅在 API 调用之后 触发,而 Vibrant 按顺序有 运行?
您不能将 属性 添加到 Vue 中的对象并使其成为反应式;您必须使用 Vue.set 方法。
请尝试将 forEach 块替换为以下内容,这会使用 Vue.set 添加新的 属性:
for (i=0; i<projects.length; i++)
Vibrant.from(`https:${projects[i].fields.thumbnail.fields.file.url}`)
.getPalette()
.then(palette => (Vue.set(projects[i].fields, accent, palette.Vibrant.hex)))
);
更新:在这种情况下,将格式从 forEach 更改为传统的 for 循环可能是无意义的,因为进行的分配是针对项目 属性 的对象而不是原语。
我并没有在 Whosebug 上花费很多时间,如果上述答案有效,我真的很高兴。
但我希望从那个答案中你会收到控制台警告,告诉你不要直接改变状态。
现在发生这种情况是因为虽然 Vue.set() 实际上确实帮助 Vue 反应式地理解已经发生的变化,可能深深地嵌套在一个对象中。
这里的问题是因为你在循环对象,一直在改变它,提交(Mutator 调用)不是一个改变状态 - Vue.set() 实际上是在每次迭代中改变它.
我目前正在构建一个 Vue 应用程序,它使用 Contentful API 中的数据。对于每个条目,我都有一个 thumbnail
(图像)字段,我想从中提取突出的颜色作为十六进制值,并将它们存储在应用程序其他地方使用的状态。
使用 Vuex 操作 (getAllProjects) 查询 API、运行 Vibrant (node-vibrant) 并将响应提交到状态。
async getAllProjects({ commit }) {
let {
fields: { order: order }
} = await api.getEntry("entry");
let projects = order;
projects.forEach(p =>
Vibrant.from(`https:${p.fields.thumbnail.fields.file.url}`)
.getPalette()
.then(palette => (p.fields.accent = palette.Vibrant.hex))
);
console.log(projects);
// Commit to state
commit("setAllProjects", projects);
}
当我在调用 commmit
之前记录 projects
的内容时,我可以看到我在 之后添加的十六进制值是 accent
键。但是,当我在 devtools 中检查突变有效载荷时,accent
键丢失了,因此最终没有进入状态。
我如何构建这些任务,以便 commit
仅在 API 调用之后 触发,而 Vibrant 按顺序有 运行?
您不能将 属性 添加到 Vue 中的对象并使其成为反应式;您必须使用 Vue.set 方法。
请尝试将 forEach 块替换为以下内容,这会使用 Vue.set 添加新的 属性:
for (i=0; i<projects.length; i++)
Vibrant.from(`https:${projects[i].fields.thumbnail.fields.file.url}`)
.getPalette()
.then(palette => (Vue.set(projects[i].fields, accent, palette.Vibrant.hex)))
);
更新:在这种情况下,将格式从 forEach 更改为传统的 for 循环可能是无意义的,因为进行的分配是针对项目 属性 的对象而不是原语。
我并没有在 Whosebug 上花费很多时间,如果上述答案有效,我真的很高兴。
但我希望从那个答案中你会收到控制台警告,告诉你不要直接改变状态。
现在发生这种情况是因为虽然 Vue.set() 实际上确实帮助 Vue 反应式地理解已经发生的变化,可能深深地嵌套在一个对象中。
这里的问题是因为你在循环对象,一直在改变它,提交(Mutator 调用)不是一个改变状态 - Vue.set() 实际上是在每次迭代中改变它.