Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-

简介: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-

image.png

原因:

子组件改了父组件的值

避免修改父组件传过来的值

image.png

注意: 如果value是obj,需要进行深拷贝。


可以参考: https://blog.csdn.net/u013948858/article/details/118342541

image.png

文章目录

1. 需求及报错

2. 分析原因

2.1 这是什么原因造成?

3. 解决方案: 使用 v-on 明确实现修改方式

4. 参考

1. 需求及报错

需求: 使用的场景是:A 组件中引用 B 组件,使用 v-model 给 B 传递参数,B 使用 props: { value } 接收内容,在 B 中根据逻辑直接修改并赋值 value, 事件触发后在浏览器 console 里看到报错,内容如下:

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"

2. 分析原因

从报错内容上来看,我们改动了子组件中引用的父组件的变量,也就是 props 中的数据,是不能这么操作的;


从提示的信息上看,使用 mutated 是否可行?


在 Vue2 中组件 props 中的数据只能单向流动,即只能从父组件通过组件的 DOM 属性 attribute 传递 props 给子组件,子组件只能被动接收父组件传递过来的数据,并且在子组件中,不能修改由父组件传来的 props 数据。


组件内不能修改props的值,同时修改的值也不会同步到组件外层,即调用组件方不知道组件内部当前的状态是什么


2.1 这是什么原因造成?

在 vue1.x 版本中利用 props 的 twoWay 和 .sync 绑定修饰符就可以实现 props 的双向数据绑定。


在 vue2.0 中移除了组件的 props 的双向数据绑定功能,如果需要双向绑定需要自己来实现。

在 vue2.0 中组件的 props 的数据流动改为了只能单向流动,即只能由(父组件)通过组件的 v-bind:attributes 传递给(子组件),子组件只能被动接收父组件传递过来的数据,并在子组件内不能修改由父组件传递过来的 props 数据。


官方文档解释:


prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。

虽然废弃了props的双向绑定对于整个项目整体而言是有利且正确的,但是在某些时候我们确实需要从组件内部修改props的需求


在 Vue2.0 中,实现组件属性的双向绑定方式(算不上是绑定了,算是异步修改), 可使用如下方法


v-model 指令或 .sync 修饰符

将修改属性的方法通过 v-bind 传给子组件调用,子组件直接按方法使用即可

将修改属性的方法通过 v-on 传递给子组件调用,使用 $emit() 实现回调修改

或者使用 this.$parent 去修改

3. 解决方案: 使用 v-on 明确实现修改方式

也是为了代码可读性


不要直接修改从父组件传过来的 props 数据,在data函数中重新定义一个变量,将props数据数据赋值在data变量上,后面修改data变量即可。如下:


B 组件接受 A组件的参数

name: "B",
props: {
  father: {
    type: String,
    default: null
  }
}
data(){
  return{
    father_a : this.father
  }
}

如果想要监听 A 组件中传递过来的变量,从而修改 B 组件中的某个数据,可以使用 watch 这个监听函数来监听。如下:

name: "B",
props: {
  father: {
    type: String,
    default: null
  }
}
data(){
  return{
    father_a: this.father
    son: ''
  }
}
//监听函数,只要从父组件中传过来的father变量发生变化,
//子组件中定义的son变量就会赋值为“儿子”
watch:{
  father(val, valOld){
    this.son = "儿子"
  }
}
如果 
B
 想修改 
A
 传递过来的属性可以使用 
$emit
A
<B :father="a" @change="changeA" />
export default {
  name: 'A',
  data() {
    return {
      a: 'A的变量'
    }
  },
  methods: {
    changeA(val) {
      this.a = val
    }
  }
} 
<script>
export default {
  name: 'B',
  props: {
    father: {
      type: String,
      default: null
    }
  },
  data() {
  },
  watch:{
    father(val, valOld){  // 这里也可以在 data 定义变量 并将 father 赋值给他, 在这里监控这个变量
      // 这里做如果 father 变量变化了,子组件需要处理的逻辑
    }
  },
  methods: {
    changeAFather() { // 谁来调用它? 是子组件的业务操作
      this.$emit('change', val)
    }
  }
}
</script>
至此,子组件内数据与父组件的数据的双向绑定,组件内外数据的同步:
组件内部自己变了告诉外部,外部决定要不要变。
vue1.0
 数据双向绑定在 
vue2.0
 版本中被抛弃了呢?通过案例也可以发现双向绑定的 
props
 代码多,不利于组件间的数据状态管理,尤其是在复杂的业务中更是如此,不易理解和阅读其中的逻辑,所以尽量不使用这种方式的双向绑定,过于复杂的数据处理使用vuex来进行数据管理。

 


相关文章
|
4天前
|
JavaScript
鬼火起~为什么报错[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the
鬼火起~为什么报错[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the
|
4天前
|
JavaScript
解决报错did you register the component correctly? For recursive components, make sure to provide the “na
解决报错did you register the component correctly? For recursive components, make sure to provide the “na
|
4天前
|
小程序 JavaScript
Avoid mutating a prop directly since the value will be overwritten whenever the parent comp
Avoid mutating a prop directly since the value will be overwritten whenever the parent comp
|
10月前
Unknown custom element: <add-employee> - did you register the component correctly? For red cursive c
原因: 1.组件名没写对(导入和注册不对应) 2.components少写了个s 3.组件命名最好是驼峰命名 4.导入时语法错误 5.代码中有两个components,后一个的值把前一个覆盖了 6.组件直接循环套用了
|
10月前
|
JavaScript
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent .(二)
1.在data中声明一个变量接收props的值,然后再去改变data里的这个值 2. 用computed属性 3.用data保存数据,watch监听
|
10月前
|
JavaScript
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent .(一)
大致意思就是props接收到的从父组件传过来的tableData不能直接修改。
|
JavaScript 算法 前端开发
Property xxx was accessed during render but is not defined on instance
目前el-form的model主要用表单验证的,也就是配合el-form的rules和el-form-item的prop来使用的。不信的话,你可以增加一个rules和prop(为了调用验证方法,也el-form也加一个ref属性,相当于id或者class选择器的意思),但是不写model,然后验证的话,会提示缺少model,导致无法验证成功。
Property xxx was accessed during render but is not defined on instance
|
JavaScript
【解决方案】[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the pa
【解决方案】[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the pa
1424 0
the code place where the binding is converted to final value displayed in u
the code place where the binding is converted to final value displayed in u
104 0
the code place where the binding is converted to final value displayed in u