问题描述

vue2框架中,父组件传递一个对象给子组件的props,子组件监听后深拷贝到自己的data,用vue-dev-tools观察发现,prop有值但是data无值。

问题代码

父组件 Father.vue

<template>
  <div>
    <SonComponent :someObj="someObj" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      someObj: {}, // 需要传递给子组件的对象
    };
  },
  watch: {
    // someObj需要监听这个异步获取的数据,给对象赋值
    anotherObj(val) {
      val.forEach(item => {
        someObj[item.a] = item.b; // 致命的写法
      });
    },
  },
};
</script>

子组件 SonComponent.vue

<script>
import { cloneDeep } from 'lodash';

export default {
  props: {
    someObj: Object,
  },
  data() {
    return {
      myObj: {},
    };
  },
  watch: {
    someObj: {
      hander(val) {
        myObj = cloneDeep(val);
      },
      immediate: true,
    },
  },
};
</script>

错误分析

导致这个Bug的原因是,父组件给someObj 对象的属性赋值时,是直接给属性赋值,这样虽然父组件的原始数据上变化了,但是子组件是监听不到这个变化的。这个时候如果父组件用这个值去渲染视图,视图也是渲染不了的。

由于一开始一直以为是子组件的代码写错了,排查了好久。后面思路一转换,会不会是父组件写错了,改了一行代码,果然可以用了。

解决方案

父组件 Father.vue

someObj[item.a] = item.b;

==== 将这行错误代码替换为》》》

this.$set(someObj, item.a, item.b);

DDD7
265 声望5 粉丝

幻想某一天顶替产品经理的前端妹砸(>V