首页 > 解决方案 > 取消 vue 组件中的属性更新

问题描述

我有一个 Vue 组件来更新用户数据

<template>
  <form>

     ... fields to update user property ...

    <button class="btn btn-primary" :disabled="!isDirty" @click.prevent="submit">Submit</button>
    <button class="btn btn-default" @click.prevent="cancel">Cancel</button>
  </form>
</template>

<script>
export default {
  props: ["user"],
  methods: {
    submit() {
      this.$emit("formIsSubmitted", true);
    },
    cancel() {

      ????

    }
  }
};
</script>

当我提交时,父组件中的用户被更新,因为它是一个通过引用传递的对象。单击取消按钮时,如何将用户属性“重置”为其原始值?

我尝试在 created() 事件中创建一个克隆对象,然后将用户重置为该对象,但随后出现以下错误:

避免直接改变 prop,因为只要父组件重新渲染,该值就会被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“用户”

标签: vue.jsvue-component

解决方案


所以基本上你想防止改变传递的道具引用。

一种方法是使用计算的 getter/setter:

...
props: ["user],
data(){return {
  [propname + '_']: ""
}.
computed: {
  [propname]: {
    get(){
       return this[propname + '_'] || this.user[propname]
       // or call cancel in mounted and just 
       return this[propname + '_']
    },
    set(value){
       this[propname + '_'] = value
    }
  }
}
...
cancel(){
   this[propname] = this.user[propname]
}

ofc 可以循环假设这等于展平和复制:

created(){
  this.cancel()
}
props: ["user"]
data(){return {flatcopy: {}}}
cancel(){
  Object.entries(this.user)
  .forEach(([key,value]) => this.$set(this.flatcopy, key, value)
}

或某种混合风格(未经测试,但我认为应该以这种方式工作):

function mixin(propname){
return {
...
mounted(){
  if(this.cancel && typeof this.cancel == "function"){
     const cancel = this.cancel.bind(this)
     this.cancel = ()=> {

         this[propname] = this.user[propname]
         cancel()
     }
   } else {
         this.$set(this, cancel, (()=>{this[propname] = this.user[propname]}))
   }
}
props: ["user],
data(){return {
  [propname + '_']: ""
}.
computed: {
  [propname]: {
    get(){
       return this[propname + '_'] || this.user[propname]
       // or call cancel in mounted and just 
       return this[propname + '_']
    },
    set(value){
       this[propname + '_'] = value
    }
  }
}


usage: 
{
  mixins: [mixin('anyname')]
}

推荐阅读