admin管理员组文章数量:1296895
I am trying to get my head wrap around how props are passed to child ponents and how they are updated from there.
// parent.vue
<template>
<div>
<div v-for="elem in getCurrentArray">
<child-ponent :elem="elem"></child-ponent>
</div>
<button @click.prevent="currentIdx--">Prev</button>
<button @click.prevent="currentIdx++">Next</button>
</div>
</template>
<script>
export default {
ponents : {
ChildComponent
},
data(){
return {
arr : [ ["A", "B", "C" ], [ "D", "E" ]], // this would be populated from vue store
currentIdx : 0
}
},
puted : {
getCurrentArray(){
return this.arr[this.currentIdx]
}
},
}
</script>
// child.vue
<template>
<div>Prop: {{elem}} <input type="text" v-model="myinput" @blur="save" /></div>
</template>
<script>
export default {
props : [ "elem" ],
data(){
return {
myinput : this.elem
}
},
methods : {
save(){
// this.$store.dispatch("saveChildElement", { myinput }
}
},
mounted(){ console.log( this.elem + " being rendered" ) }
}
</script>
In this example, I have two sets of arrays ['A','B','C'] and ['D','E']. On page load, the first set is rendered thru child ponents.
Looks good. However, when I click next to go to the second set, I get this:
So, while the props are being passed correctly, the textbox input values are not updated. When I checked the console.log, it's clear that vue does not re-render child ponents for "D" and "E". Instead, it simply uses the existing ponents for "A" and "B".
Is there a way to force vue to re-render the ponents? If not, how can I make sure that the textbox input gets the latest prop values? Keep in mind that I want to be able to save changes to the input values via vue store.
I am trying to get my head wrap around how props are passed to child ponents and how they are updated from there.
// parent.vue
<template>
<div>
<div v-for="elem in getCurrentArray">
<child-ponent :elem="elem"></child-ponent>
</div>
<button @click.prevent="currentIdx--">Prev</button>
<button @click.prevent="currentIdx++">Next</button>
</div>
</template>
<script>
export default {
ponents : {
ChildComponent
},
data(){
return {
arr : [ ["A", "B", "C" ], [ "D", "E" ]], // this would be populated from vue store
currentIdx : 0
}
},
puted : {
getCurrentArray(){
return this.arr[this.currentIdx]
}
},
}
</script>
// child.vue
<template>
<div>Prop: {{elem}} <input type="text" v-model="myinput" @blur="save" /></div>
</template>
<script>
export default {
props : [ "elem" ],
data(){
return {
myinput : this.elem
}
},
methods : {
save(){
// this.$store.dispatch("saveChildElement", { myinput }
}
},
mounted(){ console.log( this.elem + " being rendered" ) }
}
</script>
In this example, I have two sets of arrays ['A','B','C'] and ['D','E']. On page load, the first set is rendered thru child ponents.
Looks good. However, when I click next to go to the second set, I get this:
So, while the props are being passed correctly, the textbox input values are not updated. When I checked the console.log, it's clear that vue does not re-render child ponents for "D" and "E". Instead, it simply uses the existing ponents for "A" and "B".
Is there a way to force vue to re-render the ponents? If not, how can I make sure that the textbox input gets the latest prop values? Keep in mind that I want to be able to save changes to the input values via vue store.
Share asked Sep 22, 2019 at 15:28 user3628119user3628119 3575 silver badges15 bronze badges 2- Yes, looks like a duplicate. However, that post is missing the sample code (broken link), so it may not be as useful – user3628119 Commented Sep 23, 2019 at 3:39
- My bad, pletely missed that. Thanks. – yuriy636 Commented Sep 23, 2019 at 20:35
4 Answers
Reset to default 3Add a key as cool-man says, it will fix the issue.
However, your check for ponent re-rendering is flawed, you used the child mounted life cycle, and because you see it running only once you think the ponent isn't re-rendering. But this is wrong. "mounted" happens only once in a ponent life cycle, and because you're using the same ponent for ['A','B','C'] and then for ['D','E'] vue knows not to re-create the ponents and simply re-renders them with the new props.
Try to add the :Key
prop in the v-for
loop
<div v-for="elem in getCurrentArray" :key="elem">
To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item:
... List Rendering - Maintaining State
Keys must be unique, if you have two or more same value in your array, for example ['A',' B', 'A']
it will create a conflict, the best way to overe this is to add a generated unique 'ID' for each instance.
Or In alternative (a short term solution)
You can use the loop index in bination with the array value, this should give you a more or less unique key.
<div v-for="(elem, index) in getCurrentArray" :key="elem + index">
You can ask your ponent to re-render. (The other answers of updating the key is correct).
However, if you do want to use Vuex to manage state, I suggest you do that first as there is (essentially) a different mechanism that will do that re-render for you, and feel much easier. Namely the “puted properties” will likely solve that for you.
I remember getting stuck on this when I was starting out, and once I implemented Vuex I wished I had just done it that way, which kind of just solved the problem for me as part of its workflow. (It will likely mean you don’t need to update key, but you have that in case you have a plex situation when you still need to force a re-render).
Edit: As @JonyB rightly pointed out, you are trying to re-render the whole ponent. If you think about it, what you really want to do here is not re-render the whole ponent, but merely update the state. Therefore, once you implement Vuex, it will likely solve this for you as it allows you to deal with state separately.
All you need to add the key
to the v-for
loop and it will work.
Replace
<div v-for="elem in getCurrentArray">
with
<div v-for="elem in getCurrentArray" :key="elem">
Ref: https://v2.vuejs/v2/guide/list.html#v-for-with-a-Component
本文标签: javascriptVuejs child components are not being rerenderedStack Overflow
版权声明:本文标题:javascript - Vue.js: child components are not being re-rendered - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741615453a2388499.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论