Vue - 嵌套组件不会更新其数据并重新渲染
Posted
技术标签:
【中文标题】Vue - 嵌套组件不会更新其数据并重新渲染【英文标题】:Vue - Nested component won't update its data and re-render 【发布时间】:2020-07-09 15:45:13 【问题描述】:这里是场景。我可以上传一个LiteratureReview
,每个可以包含一个或多个Quote
。所以我拥有的是LiteratureReview
(Parent) 和Quote
(Child) 组件。我使用 Axios 获取和发布数据。我的后端是 Laravel。
LiteratureReview
和 Quote
从应用实例中获取数据。发送 post 请求后,LiteratureReview
将更新并重新呈现页面。但是当我想在其文献综述中添加Quote
时,它并没有更新,我需要刷新页面。
app.js(或 main.js)
export const app = new Vue(
el: '#app',
data: function ()
return
literatureReviews: [],
quotes: [],
,
mounted()
axios.all([
axios.get('/literature-review'),
axios.get('/quote')
]).then(axios.spread((first_response, second_response) =>
this.literatureReviews = first_response.data
this.quotes = second_response.data
))
);
index.blade.php
<literature-review v-for="(literatureReview, index) in literatureReviews" v-bind:loop="index + 1"
v-bind:key="literatureReview.id" v-bind:literature_review_id="literatureReview.id"
v-bind:topic="literatureReview.topic" v-bind:type="literatureReview.type"
v-bind:year="literatureReview.year" v-bind:link="literatureReview.link"></literature-review>
文学评论(组件;父级)
<template>
<div class="literature-card mb-5 rounded">
.
.
.
<quote v-for="quote in filterByLiteratureReview(quotes, literature_review_id)" v-bind:key="quote.id"
v-bind:literature_review_id="literature_review_id" v-bind:quote="quote.quote" v-bind:page="quote.page"></quote>
</div>
</template>
<script>
import app from '../app.js'
import store from '../app.js'
export default
props: ['loop', 'literature_review_id', 'topic', 'type', 'year', 'link'],
data()
return
quotes: app.quotes,
sharedObject: store,
,
methods:
filterByLiteratureReview(quotes, literature_review_id)
return this.quotes.filter(quote => quote.literature_review_id == literature_review_id)
,
updateLitIdForAddingQuote(value)
this.sharedObject.setLiteratureReviewIdAction(value)
,
</script>
引用(组件;子)
<template>
<div>
<div class="row no-gutters px-3 pt-3">
<div class="col" style="white-space: pre-wrap;"> quote </div>
</div>
<div class="row no-gutters" style="border-bottom: solid black 2px;">
<div class="col py-4 pr-3 text-right">Pg page </div>
</div>
</div>
</template>
<script>
export default
props: ['id', 'literature_review_id', 'quote', 'page'],
</script>
Axios 发表文献评论
axios.post('/literature-review',
topic: this.topic,
type: this.type,
year: this.year,
link: this.link,
).then( response =>
$('#addSourceModal').modal('hide')
).finally(
axios.get('/literature-review').then(response => app.literatureReviews = response.data)
)
Axios 发布报价
axios.post('/quote',
literature_review_id: this.sharedObject.state.literature_review_id,
quote: this.quote,
page: this.page
).then( response =>
console.log(response)
$('#addQuoteModal').modal('hide')
// location.reload();
).finally(
axios.get('/quote').then(response => app.quotes = response.data)
)
【问题讨论】:
当您发出帖子请求时,您是否在literature-review
中获得更新的道具?
我从一个弹出模式更新数据,它本身是一个组件但与这两个无关
我的意思是,发完帖子后,你能在literature-review
componet 看到更新的道具吗?
哦,对于 literature-review
是的,但对于 quote
不是,尽管方法相同
这是由于您的 filterByLiteratureReview
方法而发生的。当数据发生变化时,它不知道再次运行。您可以尝试将其转换为计算属性。或者您需要传递一个key
,它会在您发帖时更新。当key改变时,会强制Quote
重新渲染。
【参考方案1】:
这个article 在某种程度上帮助我解决了这个问题。所以基本上,数据是从弹出模式的提交按钮更新的。我制作了这个按钮来向根this.$root.$emit('forceRerender')
发出一个事件,该事件在创建时由LiteratureReview
、this.$root.$on('forceRerender', this.forceRerender)
接收。 LiteratureReview
组件然后运行其包含axios.get('/quote').then(response => this.quotes = response.data)
的forceRerender()
。
模态
<script>
export default
props: ['target'],
methods:
submit()
this.$emit('submit')
this.$root.$emit('forceRerender')
</script>
文学评论部分
<script>
import
app
from '../app.js'
import
store
from '../app.js'
export default
props: ['loop', 'literature_review_id', 'topic', 'type', 'year', 'link'],
data()
return
quotes: app.quotes,
sharedObject: store,
,
created()
this.$root.$on('forceRerender', this.forceRerender)
,
methods:
filterByLiteratureReview(quotes, literature_review_id)
return this.quotes.filter(quote => quote.literature_review_id == literature_review_id)
,
updateLitIdForAddingQuote(value)
this.sharedObject.setLiteratureReviewIdAction(value)
,
forceRerender()
axios.get('/quote').then(response => this.quotes = response.data)
</script>
【讨论】:
以上是关于Vue - 嵌套组件不会更新其数据并重新渲染的主要内容,如果未能解决你的问题,请参考以下文章