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来进行数据管理。

 


相关文章
uniapp 获取元素高度
uniapp 获取元素高度
1029 0
【UI】 element -ui select下拉框label显示多个值
【UI】 element -ui select下拉框label显示多个值
649 1
|
移动开发 API
Uniapp解决app和H5跨域问题
Uniapp解决app和H5跨域问题
3158 0
Uniapp解决app和H5跨域问题
el-input的number类型里输入e、+、-符号返回值为空?
el-input的number类型里输入e、+、-符号返回值为空?
794 0
|
8月前
|
C#
C# 实现图片压缩工具(基础版)
基于 System.Drawing 实现图片尺寸缩放与质量压缩,支持常见格式。通过计算缩放比例生成新图像,并调整压缩质量以减小文件大小。适用于 .NET 平台,需安装 System.Drawing.Common NuGet 包。
|
5月前
|
开发框架 IDE 开发工具
Visual Studio 2026 安装教程:自定义路径+组件选择+桌面快捷方式(64位)
Visual Studio 2026是Windows平台主流IDE,集UML设计、代码管理、开发调试等全生命周期工具于一体。本文详解离线安装步骤:解压→管理员运行→选工作负载→改安装路径→完成配置,支持快捷方式创建。(239字)
2413 0
|
前端开发 JavaScript 算法
使用 JavaScript 数组方法实现排序与去重
【10月更文挑战第21天】通过灵活运用 `sort()` 方法和 `filter()` 方法,我们可以方便地实现数组的排序和去重。同时,深入理解排序和去重的原理,以及根据实际需求进行适当的优化,能够更好地应对不同的情况。可以通过实际的项目实践来进一步掌握这些技巧,并探索更多的应用可能性。
575 59
解决 TypeError: Cannot read property ‘tapPromise‘ of undefined
解决 TypeError: Cannot read property ‘tapPromise‘ of undefined
869 0
|
存储 JavaScript
vuex【解决方案】刷新页面数据丢失(两种方法)—— 含 vuex-along 教程
vuex【解决方案】刷新页面数据丢失(两种方法)—— 含 vuex-along 教程
1338 0
开发指南029-el-table-column对齐属性
按开发文档和正常理解,el-table-column具有属性align,可以填left,center,right控制内容的对齐方式

热门文章

最新文章