Вы должны понимать, иерархию компонентов, которую вы имеете, и то, как вы передаете реквизит, определенно, ваш случай особенный и обычно не встречается разработчиками.
Родительский компонент -myProp-> Дочерний компонент -myProp-> Внучатый компонент
Если myProp изменяется в родительском компоненте, это будет отражено и в дочернем компоненте.
И если myProp изменяется в дочернем компоненте, это будет отражено и в компоненте внука.
Таким образом, если myProp изменяется в родительском компоненте, это будет отражено в компоненте внука. (Все идет нормально).
Поэтому вниз по иерархии вам не нужно ничего делать, реквизит будет по своей сути реактивным.
Теперь говорим о повышении в иерархии
Если myProp изменяется в компоненте grandChild, он не будет отражен в дочернем компоненте. Вы должны использовать модификатор .sync в дочернем элементе и генерировать событие из компонента grandChild.
Если myProp изменяется в дочернем компоненте, он не будет отражен в родительском компоненте. Вы должны использовать модификатор .sync в родительском и генерировать событие от дочернего компонента.
Если myProp изменяется в компоненте grandChild, он не будет отражен в родительском компоненте (очевидно). Вы должны использовать дочерний модификатор .sync и событие emit из компонента grandchild, затем наблюдать за пропуском в дочернем компоненте и генерировать событие при изменении, которое прослушивается родительским компонентом с использованием модификатора .sync.
Давайте посмотрим код, чтобы избежать путаницы
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>
Но после этого вы не заметите кричащих предупреждений о том, что
«Избегайте прямого изменения свойства, так как значение будет перезаписываться при повторном рендеринге родительского компонента».
Опять же, как я упоминал ранее, большинство разработчиков не сталкиваются с этой проблемой, потому что это анти паттерн. Вот почему вы получаете это предупреждение.
Но для того, чтобы решить вашу проблему (в соответствии с вашим дизайном). Я считаю, что вы должны сделать вышеупомянутую работу (взломать, если честно). Я все еще рекомендую вам пересмотреть свой дизайн и сделать его менее подверженным ошибкам.
Я надеюсь, что это помогает.