Vue.js 中父级数据更改时如何重新渲染内部组件
Posted
技术标签:
【中文标题】Vue.js 中父级数据更改时如何重新渲染内部组件【英文标题】:How to re-render inner component when data from parent changes in Vue.js 【发布时间】:2021-11-28 05:01:08 【问题描述】:我试图在父组件中更新某些值时从 API 获取一些数据,然后在子组件中使用它。我尝试了几件事,但都没有成功。
这是我的组件的简化版本:
家长
<template lang="html">
<div id="wrapper">
<h4>My Super Component</h4>
<button v-on:click="setListID">Load another list</button>
<ChildComponent :usernames="usernames"></ChildComponent>
</div>
</template>
<script>
import ChildComponent from "./ChildComponent.vue"
export default
components:
ChildComponent
,
data()
return
listID: 0,
usernames: undefined,
,
watch:
listID: function(newID)
this.usernames = getUsernames(newID)
,
methods:
setListID()
let id = +prompt("Input the list ID");
if (Number.isNaN(id))
alert("Please input a valid number");
else
this.listID = id;
,
async mounted()
this.usernames = await getUsernames(this.listID)
function sleep(ms)
return new Promise(resolve => setTimeout(resolve, ms));
// Simulating an API call
async function getUsernames(listID)
sleep(200).then(() =>
switch (listID)
case 0:
return ['Pierre', 'Paul', 'Jaques']
case 1:
return ['Riri', 'Fifi', 'Loulou']
case 2:
return ['Alex', 'Sam', 'Clover']
default:
return []
)
</script>
儿童
<template lang="html">
<p v-for="username in usernames">username</p>
</template>
<script>
export default
props:
usernames: Object
,
</script>
我在孩子身上得到的道具是一个承诺,我试图传递一个数组,但由于获取数据的函数是异步的,我不能等待手表,我有点卡住了。
更新:
我认为问题来自此代码:
// Simulating an API call
async function getUsernames(listID)
await sleep(200).then(() =>
switch (listID)
case 0:
return ['Pierre', 'Paul', 'Jaques']
case 1:
return ['Riri', 'Fifi', 'Loulou']
case 2:
return ['Alex', 'Sam', 'Clover']
default:
return []
)
return 'returned too early'
函数总是返回'returned too early'
。当我删除这个默认返回时,undefined
被返回并且我的子组件使用它作为数组。
【问题讨论】:
您没有在 v-for 中使用 :key 属性。但无论如何,我认为在需要时重新渲染子组件的最佳方法是使用 $forceUpdate 我已经尝试使用$forceUpdate
,但我认为我没有正确使用它。能给我举个例子吗?
试试这个话题:michaelnthiessen.com/force-re-render
是我关注的那个lol,没用
一侧节点,使用 await 或 .then,但不能同时使用。
【参考方案1】:
尝试如下 sn-p
Vue.component('Child',
template: `
<div class="">
<p v-for="username in usernames">username</p>
</div>
`,
props:
usernames: Array
,
)
new Vue(
el: '#demo',
data()
return
listID: 0,
usernames: undefined,
,
watch:
listID: async function(newID)
this.usernames = await this.getUsernames(newID)
,
methods:
setListID()
let id = +prompt("Input the list ID");
if (Number.isNaN(id))
alert("Please input a valid number");
else
this.listID = Number(id);
,
sleep(ms)
return new Promise(resolve => setTimeout(resolve, ms));
,
getUsernames(listID)
return this.sleep(200).then(() =>
switch (listID)
case 0:
return ['Pierre', 'Paul', 'Jaques']
case 1:
return ['Riri', 'Fifi', 'Loulou']
case 2:
return ['Alex', 'Sam', 'Clover']
default:
return []
)
,
async mounted()
this.usernames = await this.getUsernames(this.listID)
)
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div id="wrapper">
<h4>My Super Component</h4>
<button v-on:click="setListID">Load another list</button>
<Child :usernames="usernames"></ChildComponent>
</div>
</div>
【讨论】:
【参考方案2】:似乎与您发送数组的道具有关,但在您期望对象的子组件中。 试试下面的代码看看
<template lang="HTML">
<p v-for="(username, index) in usernames" :key="index">username</p>
</template>
<script>
export default
props:
type: Object, // or Aarray
default: () =>
return // [] if the type is array
,
</script>
【讨论】:
它也不起作用以上是关于Vue.js 中父级数据更改时如何重新渲染内部组件的主要内容,如果未能解决你的问题,请参考以下文章