如果子组件发生更改,如何重新渲染父组件
Posted
技术标签:
【中文标题】如果子组件发生更改,如何重新渲染父组件【英文标题】:How can I rerender parent component if child component changes 【发布时间】:2020-01-20 13:46:09 【问题描述】:我正在开发一个书籍跟踪器应用程序,它可以跟踪您已阅读或将要阅读的书籍。我在服务器端使用 Vue.js 和 Express.js。共有三个列表(类别)。我正在尝试应用按钮更改书籍类别的功能(即从“当前阅读”到“已完成”)。有用。但我必须重新加载整个页面才能看到结果。 所以我有一个组件“我的书”,其中包括组件“书单”,我将“listType”作为道具传递并呈现所有三个列表。在“书单”组件中,我有 v-for 渲染所有书籍并使用“书”组件和书对象作为道具。 'book' 组件有用于更改类别的按钮。因此,当我按下其中一个按钮时,我可以在服务器端更改 listType 并更新数据库条目,甚至重新渲染“书”组件,但是如果不刷新整个列表,我就无法达到我的书从一个列表移动到另一个列表的地步页。
//mybooks 组件
<template>
<BookList listType="current" />
<BookList listType="wantToRead" />
<BookList listType="finished" />
</template>
//书单组件
<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>
【问题讨论】:
通常,如果您希望子组件的逻辑影响父组件,那么您需要将该逻辑上移到父组件。然后,您可以作为道具或emit
传递对它的引用。否则,即使孩子的状态发生变化,您的父组件也不会受到其孩子正在做什么的影响。
【参考方案1】:
您在正确的轨道上,但您不了解 Vue 希望处理数据的方式。
你做对了
你的父组件 booklist
通过 prop v-bind :book
将数据传递给子组件 Book
现在需要做什么
当Book
发生变化时,它需要执行诸如$emit('bookChanged', book)
之类的发射事件,以便任何父组件都知道其子组件中发生了某些事情并需要做出反应。所以在我的例子中你的代码看起来像
<Book :book="bookElement" @bookChanged="RefreshMe_Method" />
此时 RefreshMe_Method 可以做几件事之一,这个简单的方法是简单地更新传递给 Prop :book
的数据,或者另一个更强力的选项是调用 this.$forceUpdate();
但我确信只是更新数据会自动刷新你想要的数据。
如何处理数据
-
家长将数据传递给孩子(想想第一天的学校午餐)。
Child 显示数据、改变数据(本地副本而不是 Prop)或执行一些特殊操作。 (扔掉蔬菜)
孩子为此感到非常自豪,它想让每个人都知道所以它@987654329@ 改变了。
所有父母都看到了这一点,并且可以从这一点开始做他们想做的事。 (将孩子接地并仅包装 Brocolli)
【讨论】:
感谢您的回答。但它不起作用。我在 Book 组件和 BookList 组件中执行 $emit 捕获它并使用方法,但是 this.$forceUpdate() 不会改变任何东西。然后我尝试对 BookList 和 MyBooks 组件($emit 并捕获它)做同样的事情并在那里尝试 forceUpdate,但效果不佳...... @NikitaSkopin 您是否正在分配数据以更新孩子的道具? forceUpdate 只会刷新渲染,如果数据相同则不会有变化。 是的,我在使用 forceUpdate 之前做过,但是做错了。所以最终我解决了我的问题。谢谢! @NikitaSkopin 如果此答案帮助您解决了问题,请将其标记为已回答。祝你编码好运!以上是关于如果子组件发生更改,如何重新渲染父组件的主要内容,如果未能解决你的问题,请参考以下文章
子组件不会重新渲染,但父组件会重新渲染。如何让子组件重新渲染?
当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件
vue的开发工具插件确实好用,能看到各个变量的变化,父子组件传值是数据驱动,如果子组件的值没有成功传回来,会导致父组件的值后面事件再触发的时候不变化,如果父组件里的值没有变化,就不会重新传给子组件的p