如果子组件发生更改,如何重新呈现父组件

时间:2019-09-19 13:43:55

标签: javascript vue.js

我正在开发一个图书追踪器应用程序,该应用程序可以跟踪您已阅读或将要阅读的书籍。我在服务器端使用Vue.js和Express.js。一共有三个列表(类别)。我正在尝试在按钮更改图书类别的情况下应用功能(即从“当前阅读”更改为“完成”)。有用。但是我必须重新加载整个页面才能看到结果。 因此,我有一个组件“我的书”,其中包括组件“书本清单”,我将“ listType”作为道具传递并呈现了所有三个清单。在'book list'组件中,​​我有v-for,它呈现所有书籍,并使用'book'组件和book对象作为道具。并且“书”组件具有用于更改类别的按钮。因此,当我按下其中一个按钮时,我可以在服务器端更改listType并更新数据库条目,甚至重新呈现“ book”组件,但是如果不刷新整个书本,我就无法达到我的书从一个列表移动到另一个列表的目的。页。

// mybooks组件

<template> 
   <BookList listType="current" />
   <BookList listType="wantToRead" />
   <BookList listType="finished" />
</template>

// booklist组件

<template> 
    <div v-for="bookElement in bookList" :key="bookElement.id">
      <Book :book="bookElement" />
    </div>
</template>

<script> 
export default {
  data() {
    return {
      bookList: []
    };
  },
  components: {
    Book
  },
  props: ["listType"],
  watch: {
    "$route.query.searchDB": {
      //once a query string search value changes, get list of books from server
      immediate: true,
      async handler(value) {
        const list = (await BooksService.index(value)).data;

        //filter books by categories
        this.bookList = list.filter(element => {
          return element.listType === this.listType;
        });
      }
    }
  }
</script>

//书籍组成部分

//template to render author, title etc
//and button for example
<button @click="changeTo('current', book.id)">Change to current</button>

<script>
import BooksService from "@/services/BooksService";
export default {
  data() {
    return {
      isCurrent: false,
      isLater: false,
      isFinished: false
    };
  },
  props: ["book"],
  mounted() {
    if (this.book.listType === "current") {
      this.isCurrent = true;
    } else if (this.book.listType === "finished") {
      this.isFinished = true;
    } else this.isLater = true;
  },
  methods: {

    async changeTo(list) {
      this.book.listType = list;

      try {
        await BooksService.put(this.book);
      } catch (err) {
        this.error = err;
      }      
    }
  }
};
</script>

1 个答案:

答案 0 :(得分:0)

您处在正确的轨道上,但您不了解Vue希望处理数据的方式。

您在做什么正确

您的父级booklist组件通过prop v-bind Book将数据传递给子级组件:book

现在需要做什么

Book中的某些内容发生变化时,它需要执行$emit('bookChanged', book)之类的发射事件,以便所有父组件都知道其子组件中发生了某些事情并需要做出反应。所以在我的示例中,您的代码看起来像

<Book :book="bookElement" @bookChanged="RefreshMe_Method"  />

这时RefreshMe_Method可以做几件事之一,这很简单,就是简单地更新传递给Prop :book的数据,或者另一个更暴力的选项是调用this.$forceUpdate();,但是我确保只需更新数据即可自动刷新所需的数据。

数据处理方式

  1. 父母将数据传递给孩子(想想第一天的学校午餐)。
  2. 子级显示数据,变异数据(本地副本而不是Prop)或执行某些特殊操作。 (扔掉蔬菜)
  3. 孩子为此感到非常自豪,因此想让所有人知道,所以$emits()有所改变。
  4. 所有父母都可以看到这一点,并且可以从此开始做自己想做的事情。 (将孩子放在地上,只打包Brocolli)