2

在我写这个问题的时候,我找到了解决问题的方法,但即便如此,我还是决定与社区分享,看看我是否以最好的方式解决了问题。

鉴于我的商店的摘要:

//  store/index.js

const store = createStore({
  state: {
    userBooks: [],
  }
  mutations: {
    setUserBooks(state, val) {
      state.userBooks.push(val);
    },
  actions: {
    addBook({ commit }, payload) {
      commit("setUserBooks", payload);
  }
})

我这样称呼这个动作:

//  Add.vue

methods: {
  addBook(book) {
    this.$store.dispatch("addBook", book);
  },
}

这给了我以下错误:

Uncaught (in promise) TypeError: state.userBooks.push is not a function
  • books是通过 a 获得的对象v-for,包含 id、title、author、thumbnail 和 ISBN 等属性。

我已经检查过这个解决方案:Push to vuex store array not working in VueJS。这正是我尝试过的,但我得到了上述错误。

我是如何解决问题的:

我注意到该book对象作为代理对象进入函数。考虑到这一点,我将代理对象转换为常规对象,如下所示:

addBook(book) {
  book = Object.assign({}, book);
  this.$store.dispatch("addBook", book);
}

为什么会出现问题?

我承认我仍然不明白为什么会出现问题。book是通过 获得v-forbooksbooks由 Google Books API 查询组装而成。查询是使用完成的axios.get().then()

已经返回给console.log(this.books)我一个代理对象,我承认我不知道这是否是预期的行为以及是否应该尝试更改它。

无论如何问题都解决了,但如果有人有任何不同的方法,我会很乐意学习新的东西。


编辑:更多代码

我决定编辑问题以显示如何books生成和填充。

<template>
    <figure v-for="(book, index) in books" :key="index">
      <Button text="+" @click="addBook(book)" />
      <!-- I omitted the use of the other elements to make things more objective. -->
    </figure>
</template>

<script>
export default {
  data() {
    return {
      books: {},
    };
  },
  methods: {
    search() {
      axios
        .get(`https://www.googleapis.com/books/v1/volumes?q=${this.seek}`)
        .then((response) => {
          this.books = response.data.items.map((item) => ({
            id: item.id,
            title: item.volumeInfo.title,
            authors: item.volumeInfo.authors || [this.$t("book.unknown-author")],
            ISBN: item.volumeInfo.industryIdentifiers?.[0].identifier ?? item.id,
            thumbnail: item.volumeInfo.imageLinks?.thumbnail ?? this.noCover,
          }));
        })
        .catch((error) => console.error(error))
    },
    addBook(book) {
      // Object.assign({}, book)
      book = { ...book };
      this.$store.dispatch("addBook", book);
    },
  },
};
</script>
4

1 回答 1

1

另一种更快的新方法是传播运算符。您在 book 对象中创建一个新对象和 spred 变量。它的工作原理与book = Object.assign({}, book)

book = { ...book }

下面是更多使用 spred 运算符的示例:

  • 您可以在数组中使用它来判断 ifval是一个带有 and 对象的数组 if not just don't type ...before val
setUserBooks(state, val) {
      state.userBooks = [...state.userBooks, ...val];
}
  • 或者例如你有一个大对象被调用user,你在这个对象中有他的address对象,他想改变它。
setUser(state, address) {
      state.user = {...state.user, address};
}
于 2021-12-27T01:33:13.837 回答