关于v-model在组件中使用会报错的问题?

通过v-model使 得父子组件的 某个变量保持一致会报错
1.有没有解决这个报错的方法
2.或者有没有更好的简便方法实现上述操作

vue.js:634 [Vue warn]: 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 being mutated: "value"

found in

---> <MyCpn>
       <Root>

代码如下

<!-- <script src="./js/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="box1">
  <p> 父组件的{{id}}</p>
  <my-cpn v-model="id"></my-cpn>
</div>

<template id="tpl">
  <div>
    <p>组件value:{{value}}</p>
    <button @click="value++">组件value++</button>
  </div>
</template>

<script>
  const MyCpn = {
    template: '#tpl',
    props: {
      value: {
        type: Number,
      }
    },
    watch: {
      value() {
        this.$emit('input', this.value)
      }
    }
  }

  Vue.component('MyCpn', MyCpn)

  const app = new Vue({
    el: "#box1",
    components: {
      MyCpn
    },
    data: {
      id: 19216811
    }
  })
</script>
阅读 3.8k
5 个回答

在子组件里不直接改父组件的id,再加一个变量做中间值,改动较小

<template id="tpl">
  <div>
    <p>组件value:{{temp}}</p>
    <button @click="handleDataChange">组件value++</button>
  </div>
</template>

<script>
  const MyCpn = {
    template: '#tpl',
    data() {
        return {
            temp: this.value
        }
    },
    props: {
      value: {
        type: Number,
      }
    },
    watch: {
      value(nv) {
        this.temp = nv
      }
    },
    methods: {
        handleDataChange() {
            this.temp++;
            this.$emit('input', this.temp)
        }
    }
  }
</script>

# 2个方法

第一个 :

// 父组件
<dialog-apply :visible.sync="dialogApplyVisible" />

// 子组件
<el-dialog
      :visible.sync="visible"
      title="申请"
      :before-close="onClose"
>

onClose() {
  this.$emit('update:visible', false)
}

第二个 :

// 父组件
<dialog-apply :visible.sync="dialogApplyVisible" @close='dialogApplyVisible = false' />

// 子组件
<el-dialog
      :visible.sync="visible"
      title="申请"
      :before-close="onClose"
>

onClose() {
  this.$emit('close')
}

这2个方法 , :before-close 是关键 ;

不要直接使用父组件的传值,每当父组件重新渲染的时候都会覆盖的
<p>组件value:{{realValue}}</p>
<button @click="value++">组件realValue++</button>
data(){
realValue:this.value
}
watch:{
realValue(newValue,oldValue){
this.$emit('input',newValue)
}
}

<button @click="add">组件value++</button>

`
methods:{

add(){
    this.$emit("input", this.value++)
}

}
`

去掉watch

`
$emit不要直接用value值回传,设一个中间参数 local_value

value 变化时 赋值给local_value

local_value 变化时 this.$emit('input', this.local_value)
`

{
    template: '#tpl',
    props: {
      value: {
        type: Number,
      }
    },
    data: {
        local_value: null
    },
    watch: {
      value: function(val) { // 父类组件变化通知子组件
        this.local_value = val
      },
      local_value: function() { // 子组件变化通知父类组件
        this.$emit('input', this.local_value)
      }
    }
  }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题