Vue.js 为什么我会得到;避免直接对道具进行变异;当使用NumericTextField时?

Vue.js 为什么我会得到;避免直接对道具进行变异;当使用NumericTextField时?,vue.js,vuex,vuetify.js,Vue.js,Vuex,Vuetify.js,我已经在VueJS中创建了一个简单的视图组件,我遇到了一个非常常见的错误: 无效直接对道具进行变异,因为该值将被覆盖 每当父组件重新渲染时。相反,请使用数据或 基于道具值计算的属性。正在变异的支柱: “价值” 这是我的密码: <template> <numeric-text-field class="mx-auto" label="Head Mass" units="kg" v-model="turbine.head_mass" /> </template&

我已经在VueJS中创建了一个简单的视图组件,我遇到了一个非常常见的错误:

无效直接对道具进行变异,因为该值将被覆盖 每当父组件重新渲染时。相反,请使用数据或 基于道具值计算的属性。正在变异的支柱: “价值”

这是我的密码:

<template>
    <numeric-text-field class="mx-auto" label="Head Mass" units="kg" v-model="turbine.head_mass" />
</template>

<script>
import NumericTextField from '@/components/common/NumericTextField'
export default {
  name: 'Turbines',
  components: {
    NumericTextField
  },
  data () {
    return {
      turbine: {}
    }
  }
}
</script>

<style scoped>
</style>

从“@/components/common/NumericTextField”导入NumericTextField
导出默认值{
名称:“涡轮机”,
组成部分:{
数字文本字段
},
数据(){
返回{
涡轮机:{}
}
}
}

奇怪的是,我得到了修改“value”的错误,但我的代码中没有value。我认为这是由数字文本字段创建的间接层造成的。当我只使用普通输入文本时,代码中不存在此问题。这是怎么回事?除了v-model之外,我是否还有其他特殊的方法将模型连接到数字文本字段?

了解道具在Vue中的工作原理很重要。这里最关键的一点是,道具是用来做广告的。如果希望它是双向数据流,则需要使用
v-model

话虽如此,你可以用几种不同的方法来做这件事。我更喜欢用这样的东西!它非常干净,代码也很容易理解

与直接修改道具不同,在
数值文本字段
组件中,当 值已更改。这就是您的
Turbines.vue
的外观:

<template>
    <numeric-text-field class="mx-auto"
    label="Head Mass"
    units="kg"
    :headMass="turbine.head_mass"
    v-on:updateHeadMass="updateHeadMass"/>
</template>

<script>
import NumericTextField from '@/components/common/NumericTextField'
export default {
  name: 'Turbines',
  components: {
    NumericTextField
  },
  data () {
    return {
      // You should consider initializing your data with the structure that matches what you expect, instead of an empty object
      turbine: {
        head_mass: ""
      }
    }
  },
  methods: {
    updateHeadMass(value) {
      this.turbines.head_mass = value;
    }
  }
}
</script>

<style scoped>
</style>
<template>
  <div>
    <label for="headMass">Head Mass</label>
    <input type="text" v-model="localHeadMass"  name="headMass"/>
  </div>
</template>

<script>
export default {
  name: "numeric-text-field",
  computed: {
    localHeadMass: {
      get() {
        return this.headMass;
      },
      set(value) {
        // Now, anytime we change this property, our parent receives the new value and updates the `headMass` prop!
        this.$emit("updateHeadMass", value);
      }
    }
  },
  props: {
    headMass: {
      type: String,
      default: "0",
      required: true
    }
  }
};
</script>

<style scoped>
</style>
如果您不喜欢上述方法,您可以使用如下观察者:

<template>
  <div>
    <label for="headMass">Head Mass</label>
    <input type="text" v-model="localHeadMass" v-on:change="updateHeadMass" name="headMass"/>
  </div>
</template>

<script>
export default {
  name: "numeric-text-field",
  data: () => {
    return {
      localHeadMass: ""
    };
  },
  props: {
    headMass: {
      type: String,
      default: "0",
      required: true
    }
  },
  methods: {
    updateHeadMass() {
      this.$emit("updateHeadMass", this.localHeadMass);
    }
  },
  watch: {
    headMass(value) {
      this.localHeadMass = value;
    }
  }
};
</script>

<style scoped>
</style>

头质量
导出默认值{
名称:“数字文本字段”,
数据:()=>{
返回{
局部人头质量:“
};
},
道具:{
人头质量:{
类型:字符串,
默认值:“0”,
必填项:true
}
},
方法:{
updateHeadMass(){
this.$emit(“updateHeadMass”,this.localHeadMass);
}
},
观察:{
人头质量(值){
this.localHeadMass=值;
}
}
};

这是我在最初发布时不知道的,在NumericTextField中发布的。我认为这是一个标准的Vueify组件,但它是由一位同事添加的。它没有正确地处理双向输入,正如原始帖子上的评论所指出的那样


诀窍是添加这个。$emit('input',value)来自@input中的NumericTextField组件,就像Ohgodwhy建议的那样。

这个。$emit('input',value)
来自
change
中的
NumericTextField组件。不要直接修改传递给您的值,因为此时它是一个属性。如果您想要双向
sync
绑定,请使用
sync
修饰符。只需显示您的NumericTextField.vue,我肯定会出现类似
的内容。还有
props
value
Oh-geez,这在Ohgodwhy和Alexander Yakushev都是正确的。我没有意识到NumericTextField是非标准的,并且是我的合作伙伴添加的代码库的一部分。否则我会把它通读一遍。而且,它也没有按照您预测的方式正确实施。我做了一些阅读,最终添加了建议的emit和@input(而不是@change)。谢谢