vue中子组件间接修改父组件传递过来的值

这篇具有很好参考价值的文章主要介绍了vue中子组件间接修改父组件传递过来的值。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、前言

Vue官方文档Props单向数据流讲解

Vue中遵循单向数据流,所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。

但是项目中总是有需求让我们来修改子组件内部传入的prop,所以才有了这篇文章,其实我们可以间接修改数据。

二、问题背景

父组件传递给子组件一个名为count数据,但是现在要在子组件中修改它的值并且实时更新页面,直接this.count是不能直接修改他的值的,控制台会报错,报错如下。所以我采用了下面两种方式间接更改。
修改父组件传过来的值,Vue,vue.js,javascript,前端

三、解决方法

方法1:子组件通过computed计算属性来间接修改父组件传递的值

父组件传值

<GoodsBasic :renderObj='renderBasic' :count='count'></GoodsBasic>

子组件更改传入的值

<template>
 <div class='goodsBasic'>
   <div>{{ incrementCount}}</div>
   <button @click='changeCount'>增加次数</button>
 </div>
</template>
<script>
export default {
  props: {
    renderObj: {
      type: Object,
      default () {
        return {}
      }
    },
    count:{
      type: Number,
      default:0
    }
  },
  data () {
    return {
      increment: this.count //新定义一个变量,并把prop传进来的值作为初始值
    }
  },
  computed:{
    incrementCount(){ //当新定义的变量变更时,计算属性也会自动更新
      return this.increment
    }
  },
  methods: {
    changeCount(){
      this.increment++
    }
  }
}
</script>

方法2:子组件data中重新定义个局部数据,把父组件prop传来的数据作为初始值使用。

父组件传值

<GoodsBasic :renderObj='renderBasic' :count='count'></GoodsBasic>

子组件更改传入的值

<template>
 <div class='goodsBasic'>
   <div>{{ increment }}</div>
   <button @click='changeCount'>增加次数</button>
 </div>
</template>
export default {
  props: {
    renderObj: {
      type: Object,
      default () {
        return {}
      }
    },
    count:{
      type: Number,
      default:0
    }
  },
  data () {
    return {
      increment: this.count  //作为初始值使用,这样做就使prop和后续更新无关了
    }
  },
  methods: {
    changeCount(){
      this.increment++
    }
  }
}
</script>

四、更改对象 / 数组类型的 props

经过个人测试发现,当传入的prop为Object类型的时候,修改组件内部的prop可以对应的改变父组件中的值。如果传入的prop为简单类型(例如String,Number等)时,浏览器会报错,提示子组件不能修改prop的值。
比如上文例子更改 renderBasic.price控制台就不会报错。

个人感觉当传入的prop为引用类型时,子组件能直接修改父组件值,是因为在堆内存中公用同一个内存地址;修改的话只是改了它的值,而内存地址并没变,所以不报错;
基本数据类型修改会报错,原因是指向的内存地址要被迫修改,所以控制台报错。

另外Vue官方文档也说了:

当对象或数组作为 props 被传入时,虽然子组件无法更改 props 绑定,但仍然可以更改对象或数组内部的值。这是因为 JavaScript 的对象和数组是按引用传递,而对 Vue 来说,禁止这样的改动,虽然可能生效,但有很大的性能损耗,比较得不偿失。
这种更改的主要缺陷是它允许了子组件以某种不明显的方式影响父组件的状态,可能会使数据流在将来变得更难以理解。在最佳实践中,你应该尽可能避免这样的更改,除非父子组件在设计上本来就需要紧密耦合。在大多数场景下,子组件应该抛出一个事件来通知父组件做出改变。

目前我们公司有个项目就是就是因为父子组件数据需要紧密耦合的,所以直接在子组件更改了数据;

上面文档说的子组件应该抛出一个事件来通知父组件做出改变,意思就是子组件调用$emit抛出一个事件名,去通知父组件,值要改变了,在父组件写一个事件做后续处理。

五、开发场景 - 父子组件实现多表单项双向绑定

我们项目中有这样一个场景,封装了一个通用子组件,是需要v-for循环得到的form表单项。然后通过props将父组件的数组传递给子组件,子组件通过emit触发事件来修改父组件的值,实现多表单项双向绑定。

首先,让我们创建一个简单的示例来说明这个过程。假设有一个父组件 ParentComponent 和一个子组件 ChildComponent,父组件中有一个数组 formData 需要传递给子组件,并且子组件需要修改 formData 中的值。

// ParentComponent.vue
<template>
  <div>
    <ChildComponent :formData="formData" @updateFormData="updateFormData" />
  </div>
</template>

<script>
import { ref} from 'vue';
import ChildComponent from './ChildComponent.vue'

const formData = ref([ // 这里使用 ref 创建响应式对象
   { name: 'Alice', age: 25 },
   { name: 'Bob', age: 30 }
]);

//  ============  保持单项数据流 修改父组件的 formData 数组值 ============
function updateFormData({index, key, value}){
   formData.value[index][key] = value; 
}
 
</script>
// ChildComponent.vue
<template>
  <div>
    <div v-for="(item, index) in formData" :key="index">
      <input v-model="item.name" @input="updateName(index, $event.target.value)" />
      <input v-model="item.age" @input="updateAge(index, $event.target.value)" />
    </div>
  </div>
</template>

<script>
import { ref, withDefaults, defineProps, onMounted, defineEmits } from 'vue'

// ------------- 传入数据 -------------
interface Props{
  formData: []
}
const props = withDefaults(defineProps<Props>(), {
  formData: () => [],
})

// ------------- 传出方法 -------------
type Emit={
  (e:'updateFormData', data:object):void
}
const emit = defineEmits<Emit>()

const updateName = (index, value) => {
   emit('updateFormData', {index, 'name', value}); // 发送事件更新父组件的 formData 值
 }

const updateAge = (index, value) => {
   emit('updateFormData', {index, 'age', value}); // 发送事件更新父组件的 formData 值
}

</script>

ChildComponent 中的表单项发生变化时,通过 emit 发送 updateFormData 事件来通知父组件修改对应的数据。

想继续深入vue传值的问题,也可以去看我之前关于vue中传值方法的文章。
vue组件之间的传值方法(父子传值,兄弟传值,跨级传值,vuex)文章来源地址https://www.toymoban.com/news/detail-611921.html

到了这里,关于vue中子组件间接修改父组件传递过来的值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VUE中子组件调用父组件的方法,父组件调用子组件的方法,父子组件互相传值和方法调用

    场景:自定义一个通用组件,需要调用父组件的方法进行计算 一、使用this.$emit()向父组件触发一个事件,父组件监听这个事件即可。 父组件: 子组件: 二、直接在子组件中通过“this.$parent.event”来调用父组件的方法。 父组件: 子组件: 三、父组件把方法传入子组件中,在子

    2024年02月04日
    浏览(39)
  • Vue中父组件如何控制子组件的值

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 在Vue开发中,父组件和子组件之间的数据传递是一项常见的任务。本文将介绍如何在Vue中实现父组件控制子组件的

    2024年02月11日
    浏览(39)
  • vue3.0 父组件调用子组件方法及获取子组件的值

    通过对比2.0的获取及调用方式这里我们也可以借鉴2.0中的this.$refs去获取3.0和2.0的refs获取的方式有点大同小异,但是思路还是一样的这里我详细的讲解一下他的调用方式及获取方法 1.第一步需要我们在父组件中定义一个方法 当我们点击这个方法的时候去调用子组件的方法 代码

    2024年02月14日
    浏览(27)
  • vue3中ref获取子组件的值

    一、 script setup 通过ref获取子组件的值或方法 父组件: 子组件: 二、setup()通过ref获取子组件值 父组件: 子组件:

    2024年02月16日
    浏览(36)
  • vue3 ts获取组件 ref元素的值

    在 Vue 3 + TypeScript 中,要获取组件 ref 元素的值,可以通过 ref 函数创建一个 ref,并将其绑定到组件的 ref 属性上。然后,可以通过访问 ref 的 .value 属性来获取该组件的实例。 以下是一个示例代码: 在上述代码中,我们首先使用 ref 函数创建了一个名为 childComponentRef 的 ref,并

    2024年02月05日
    浏览(44)
  • vue3.0子组件接收父组件的值以及调用父组件的方法

    html: 使用 v-bind即 :xxx=\\\"变量/方法\\\"向子组件传递值或者方法,下面定义变量id和变量setIds,将searchForm.id的值和setIds方法传到子组件中去 js: js: 先通过props进行接收父组件传来的值,然后再在setup里面使用第一个参数props,可以拿到父组件所有的变量以及方法 html:

    2024年02月17日
    浏览(40)
  • vue父组件和子组件数据传递

    父组件: 子组件: 父组件向子组件传值方式: 1、父组件引入子组件,注册属性message 2、子组件通过props来获取到注册的属性message 页面显示:   转存失败重新上传取消 父组件: 子组件: 子组件向父组件传值方式: 1、父组件注册事件event 2、子组件由transmit事件方法,通过

    2024年02月15日
    浏览(39)
  • vue 子组件向父组件传递参数 子传父

    子组件中写: this.$emit(\\\'RowCount\\\',res.data.RowCount); 父组件中写:             getMFGLRowCount(val){                 //父组件中的方法: 接收子组件传过来的参数值赋值给父组件的变量                 //this.totalCount = val;                 alert(\\\"这是父组件 methods 中的方法

    2024年02月09日
    浏览(33)
  • vue3中父组件与组件之间参数传递,使用(defineProps/defineEmits),涉及属性传递,对象传递,数组传递,以及事件传递

    传递属性 父组件: 子组件: 传递对象或者数组 父组件: 子组件: 父组件: 子组件:

    2024年02月13日
    浏览(43)
  • Vue父子组件值的传递【极简版】

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 在Vue.js中,父组件向子组件传递值通常通过props(属性)来实现。以下是一种典型的方法: 在父组件中,可以使用子组件的标签,并通过props属性将数据传递给子组件

    2024年01月24日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包