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() 实际上是在每次迭代中改变它.