欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue组件间的通信:子组件修改父组件的属性后报错如何解决?

程序员文章站 2022-11-28 07:58:14
前言: 最近做了购物车模块,对于组件的使用以及组件间的通信进行了摸索。实现了购物车全选、数量选择,总价计算。 总结: 一、由于vue遵循单项数据流,因此子组件是不允许修改父组...

前言:

最近做了购物车模块,对于组件的使用以及组件间的通信进行了摸索。实现了购物车全选、数量选择,总价计算。

总结:

一、由于vue遵循单项数据流,因此子组件是不允许修改父组件的属性,有可能报错如下:

[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: "result" (found in component )

解决方法:

1. 父组件:

<carTemplate name="carTemplate" v-bind:carItem="carItem" v-bind:carIndex="index" 
          v-bind:carInfo="carInfo" v-on:carMethod="carChange($event)"></carTemplate>
methods: {
    carChange(msg){  //获取子组件传过来的数据
      this.carInfo = msg;
    }
  }

子组件:

<img src='/static/assets/icon/chooseGreen.png' class='icon-choose' @click='chooseAll()' v-if='all'>
methods: {
    chooseAll () {
      this.copyAll = !this.all;
      this.$emit('allChoosed', this.copyAll);  //将数据传给父组件
    }
  }

2.这种方法我没有试过

Vue 2.3.0已回归sync修饰符。子组件想要更改父组件传入的属性,必须显式的update那个值:this.$emit('update: AttrFromParent', someVal);

二、对象不能简单被watch监听,必须深度

watch: {
    carInfo:{
          handler (newValue){ 
            var allCar = 0;
            var all = false;
            var allPrice = 0;
            for (var i = 0; i < newValue.length; i++) {
              if (newValue[i].checked==true){
                allCar++;
                allPrice = newValue[i].price *newValue[i].num +allPrice;
              }
            }
            if (allCar == newValue.length) {
              all = true;
            }
            this.all = all;
            this.allPrice = allPrice;
          },
          deep: true  //深度
      }
  },

三、改变子组件中从父组件获取的数据,如果是对象或者数组。

注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

四、Vue 不能检测到对象属性的添加或删除。

Vue不能直接在对象上添加或删除属性,必须使用Vue.set(Object,key,value)这种方式来添加属性

chooseGood () {
        var carItem = this.carItem;
        var checked = this.carItem.checked?false:true;
        this.$set(this.carItem,'checked', checked);  //添加属性
      },