父元件的屬性值通過prop傳遞給子元件,子元件直接使用,當在子元件中修改值時,父元件的值更新時提示錯誤:Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value。
原因分析:
prop 是單向綁定的:當父元件的屬性變化時,将傳導給子元件,但是不會反過來。這是為了防止子元件無意修改了父元件的狀态。
另外,每次父元件更新時,子元件的所有 prop 都會更新為最新值。這意味着不應該在子元件内部改變 prop。如果這麼做了,Vue 會在控制台給出警告。
錯誤代碼:
父元件
<template>
<div id="app">
<el-input v-model="status" placeholder="status"></el-input>
<HelloWorld :msg="status"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data () {
return {
status:"hello"
}
}
}
</script>
子元件
<template>
<div>
<el-input v-model="info"></el-input>
<h1>{{ info }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
info: this.msg
}
},
watch:{
msg(){
this.info = this.msg
}
}
}
</script>
問題處理:
方法1:對子元件修改如下
<template>
<div>
<el-input v-model="info"></el-input>
<h1>{{ info }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
info: this.msg
}
}
}
</script>
父元件修改時,不會修改子元件的值。隻是不會報錯罷了。
方法2:對子元件修改如下
<template>
<div>
<el-input v-model="info"></el-input>
<h1>{{ info }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data () {
return {
info: this.msg
}
},
watch:{
msg(){
this.info = this.msg
}
}
}
</script>
使用新的屬性info接受prop的值,并使用watch方法,監聽msg的值的變化,重新指派給info屬性。這樣父元件值變化時,子元件也同步更新。
不知道還有沒有其他更好的方法?