Javascript 警告:避免直接变异道具
我陷入了这样一种情况:我的子组件(自动完成)需要更新其父组件(曲线)的值,而父组件需要更新其中一个子组件(或在使用新的曲线组件时完全重新渲染) 在我的应用程序中,用户可以在曲线组件列表中选择一条曲线。我以前的代码工作正常,但当用户在列表中选择另一条曲线时,组件“自动完成”未更新(组件未使用父级的值更新其值) 此问题现已修复,但我收到以下警告: 避免直接改变道具,因为该值将被覆盖 每当父组件重新渲染时。相反,请使用数据或 基于道具值计算的属性。正在变异的支柱: “价值” 此警告的描述准确地解释了我对组件的预期行为。尽管有此警告,但此代码工作正常 以下是代码(部分代码已删除以简化)Javascript 警告:避免直接变异道具,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,我陷入了这样一种情况:我的子组件(自动完成)需要更新其父组件(曲线)的值,而父组件需要更新其中一个子组件(或在使用新的曲线组件时完全重新渲染) 在我的应用程序中,用户可以在曲线组件列表中选择一条曲线。我以前的代码工作正常,但当用户在列表中选择另一条曲线时,组件“自动完成”未更新(组件未使用父级的值更新其值) 此问题现已修复,但我收到以下警告: 避免直接改变道具,因为该值将被覆盖 每当父组件重新渲染时。相反,请使用数据或 基于道具值计算的属性。正在变异的支柱: “价值” 此警告的描述准确地解释了我
//curve.vue
从“./Autocomplete”导入自动完成
导出默认值{
名称:'曲线',
道具:{
值:对象
},
计算:{
曲线(){返回this.value}
},
组件:{Autocomplete}
}
//自动完成.vue
导出默认值{
名称:“自动完成”,
道具:{
价值:{
类型:字符串,
必填项:true
}
},
计算:{
内容:{
get(){返回this.value},
set(newValue){this.value=newValue}
}
}
}
很多人都得到了同样的警告,我尝试了一些我找到的解决方案,但在我的情况下,我无法使它们工作(使用事件,将Autocomplete的道具类型更改为对象,使用其他计算值,…)
有没有简单的解决办法?我是否应该忽略此警告?您可以忽略它,一切都会正常工作,但这是一种不好的做法,这是vue告诉您的。如果不遵循单一责任原则,调试代码会困难得多 Vue建议您,只有拥有数据的组件才能修改数据 不确定为什么事件解决方案(
$emit
)在您的情况下不起作用,它会抛出错误还是什么
要消除此警告,还可以使用.sync
修改器:
您可以尝试使用is代码,按照
prop
->本地数据
->$emit local data to prop
在每个组件和组件包装器中流动
ps:$emit('input',…)是v-model绑定的值(在props中)的更新
// curve.vue
<template>
<autocomplete v-model="curve.y"></autocomplete>
</template>
<script>
import Autocomplete from './autocomplete'
export default {
name: 'Curve',
props: {
value: Object
},
data() {
return { currentValue: this.value }
}
computed: {
curve() { return this.currentValue }
},
watch: {
'curve.y'(val) {
this.$emit('input', this.currentValue);
}
},
components: { Autocomplete }
}
</script>
// autocomplete.vue
<template>
<input type="text" v-model="content"/>
</template>
<script>
export default {
name: 'Autocomplete',
props: {
value: {
type: String,
required: true
}
},
data() {
return { currentValue: this.value };
},
computed: {
content: {
get() { return this.value },
set(newValue) {
this.currentValue = newValue;
this.$emit('input', this.currentValue);
}
}
}
}
</script>
//curve.vue
从“./Autocomplete”导入自动完成
导出默认值{
名称:'曲线',
道具:{
值:对象
},
数据(){
返回{currentValue:this.value}
}
计算:{
曲线(){返回this.currentValue}
},
观察:{
“curve.y”(val){
此.emit('input',此.currentValue);
}
},
组件:{Autocomplete}
}
//自动完成.vue
导出默认值{
名称:“自动完成”,
道具:{
价值:{
类型:字符串,
必填项:true
}
},
数据(){
返回{currentValue:this.value};
},
计算:{
内容:{
get(){返回this.value},
设置(新值){
this.currentValue=newValue;
此.emit('input',此.currentValue);
}
}
}
}
使用$emit
和$on
未引发任何错误,但子项未正确更新。。。但将v-model
替换为v-on
,在计算值的设置器中添加.sync
和$emit
!!谢谢!我觉得有点傻,我花了这么多时间在文档中,却没有看到.sync
…我很感激您在这个Vue.js文档中添加一个引用(加上提到文档作为源代码):以增加您的答案的价值。非常感谢。在文档中:对于要使用v-model的组件,您需要接受一个值属性并发出一个输入事件!!代码墙没有解释为什么警告会警告不良行为。
// curve.vue
<template>
<autocomplete v-model="curve.y"></autocomplete>
</template>
<script>
import Autocomplete from './autocomplete'
export default {
name: 'Curve',
props: {
value: Object
},
data() {
return { currentValue: this.value }
}
computed: {
curve() { return this.currentValue }
},
watch: {
'curve.y'(val) {
this.$emit('input', this.currentValue);
}
},
components: { Autocomplete }
}
</script>
// autocomplete.vue
<template>
<input type="text" v-model="content"/>
</template>
<script>
export default {
name: 'Autocomplete',
props: {
value: {
type: String,
required: true
}
},
data() {
return { currentValue: this.value };
},
computed: {
content: {
get() { return this.value },
set(newValue) {
this.currentValue = newValue;
this.$emit('input', this.currentValue);
}
}
}
}
</script>