Musisz zrozumieć, jaką masz hierarchię komponentów i sposób przekazywania rekwizytów, na pewno twoja sprawa jest wyjątkowa i zwykle nie spotykana przez programistów.
Komponent nadrzędny -myProp-> Komponent podrzędny -myProp-> Komponent wnuka
Jeśli myProp zostanie zmieniony w komponencie nadrzędnym, zostanie to odzwierciedlone w komponencie podrzędnym.
A jeśli myProp zostanie zmieniony w komponencie potomnym, zostanie to odzwierciedlone w komponencie wnuka.
Jeśli więc myProp zostanie zmieniony w komponencie nadrzędnym, zostanie to odzwierciedlone w komponencie wnuka. (na razie w porządku).
Dlatego w hierarchii nie musisz nic robić, rekwizyty będą z natury reaktywne.
Teraz mówimy o awansie w hierarchii
Jeśli myProp zostanie zmieniony w składniku grandChild, nie zostanie odzwierciedlony w komponencie potomnym. Musisz użyć modyfikatora .sync w potomku i emitować zdarzenie ze składnika grandChild.
Jeśli myProp zostanie zmieniony w komponencie potomnym, nie zostanie odzwierciedlony w komponencie macierzystym. Musisz użyć modyfikatora .sync w obiekcie nadrzędnym i wyemitować zdarzenie ze składnika potomnego.
Jeśli myProp zostanie zmieniony w składniku grandChild, nie zostanie odzwierciedlony w składniku nadrzędnym (oczywiście). Musisz użyć podrzędnego modyfikatora .sync i wyemitować zdarzenie z komponentu wnuka, a następnie obejrzeć prop w komponencie podrzędnym i wyemitować zdarzenie przy zmianie, które jest nasłuchiwane przez komponent nadrzędny za pomocą modyfikatora .sync.
Zobaczmy trochę kodu, aby uniknąć zamieszania
Parent.vue
<template>
<div>
<child :myProp.sync="myProp"></child>
<input v-model="myProp"/>
<p>{{myProp}}</p>
</div>
</template>
<script>
import child from './Child.vue'
export default{
data(){
return{
myProp:"hello"
}
},
components:{
child
}
}
</script>
<style scoped>
</style>
Child.vue
<template>
<div> <grand-child :myProp.sync="myProp"></grand-child>
<p>{{myProp}}</p>
</div>
</template>
<script>
import grandChild from './Grandchild.vue'
export default{
components:{
grandChild
},
props:['myProp'],
watch:{
'myProp'(){
this.$emit('update:myProp',this.myProp)
}
}
}
</script>
<style>
</style>
Grandchild.vue
<template>
<div><p>{{myProp}}</p>
<input v-model="myProp" @input="changed"/>
</div>
</template>
<script>
export default{
props:['myProp'],
methods:{
changed(event){
this.$emit('update:myProp',this.myProp)
}
}
}
</script>
<style>
</style>
Ale po tym nie pomożesz zauważyć krzyczących ostrzeżeń mówiących vue
„Unikaj bezpośredniego modyfikowania rekwizytu, ponieważ wartość zostanie nadpisana za każdym razem, gdy element nadrzędny zostanie ponownie renderowany”.
Ponownie, jak wspomniałem wcześniej, większość programistów nie napotyka tego problemu, ponieważ jest to anty-wzór. Dlatego otrzymujesz to ostrzeżenie.
Ale w celu rozwiązania problemu (zgodnie z projektem). Uważam, że musisz wykonać powyższe czynności (włamać się szczerze mówiąc). Nadal zalecam, aby przemyśleć swój projekt i uczynić go mniej podatnym na błędy.
Mam nadzieję, że to pomoże.