vue 子组件不响应父组件传过来的对象属性的值?

lizhou_pang
  • 48

问题描述

vue2.0中,子组件接收了父组件传过来的值后,没有更新响应到视图中

问题出现的环境背景及自己尝试过哪些方法

首先我的子组件页面是一个表单页面,里面的表单元素都是根据父组件传过来的一个数组渲染出来的,所以数量不固定
我就在父组件中定义了一个对象属性,来保存每个表单元素的值
但是比如当我在页面做出操作时,父组件和子组件中的那个对象都变化了,但是并没有响应到视图上,我打开了watch的深层监听,也用了this.$set方法去给对象赋值,但是视图就是没有变化

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

这是渲染的代码

<div v-for="form in formList" :key="form.fieldId">
    <div class="handle-input-single border-bottom" v-if="form.type === '1' || form.type === '2'">
      <span class="handle-title">{{form.fieldName}}</span>
      <span class="handle-select"
      @click="PickerHandle(form.fieldCode, form.type, form.column, form.fieldName)"
      v-if="form.readOnly === '0'">{{myFromData[form.fieldCode] !== null ? myFromData[form.fieldCode][0].value : '点击选择'}}</span>
      <!-- v-if="form.readOnly === '0'">{{pickerSelect(form.fieldCode)}}</span> -->
      <span class="handle-select readOnly" v-else>{{form.fieldDefault}}</span>
    </div>
</div>

这是页面的js中部分代码

props: {
    formData: Object, // 父组件中定义的对象
    formList: Array, // 表单元素的列表
    toggleStep: Boolean
  },
  data () {
    return {
      personView: '',
      myFromData: this.formData // 我在子组件内部中定义了一个变量接收了这个对象
    }
  },
  watch: {
    myFromData: {
    // 这里在对象变化的时候,没有任何输出
      handler (newVal, oldVal) {
        console.log(newVal)
        console.log(oldVal)
      },
      deep: true
    }
  },
  computed: {
    pickerSelect: () => {
      return function (e) {
        if (this.formData[e] !== null) {
          return this.formData[e][0].value
        } else {
          return '点击选择'
        }
      }
    }
  },
  methods: {
    PickerHandle (code, type, pickerList, pickerName) { // 这个是点击的方法
      if (type === '1' || type === '2') {
        this.$singlePicker({
          textTitle: pickerName,
          pickerList: pickerList,
          callback: action => {
            let picker = {}
            picker.data = action
            picker.code = code
            this.$set(this.myFromData, code, action) // 这里给子组件内部的值对象修改了值
            this.$emit('pickerHandle', picker) // 传给父组件修改了值
          }
        })
      }
    }
   }

你期待的结果是什么?实际看到的错误信息又是什么?

为什么就是不响应数据的变化呢,求大神解答,谢谢

回复
阅读 3.9k
5 个回答

如果你想watch父组件传过来的值,你的data中这个步骤是多余的

myFromData: this.formData // 不用再次赋值拿到这个值

直接watch就好:

watch: {
    formData:{
      handler (newVal, oldVal) {
        console.log(newVal)
        console.log(oldVal)
      },
      deep: true
    }
}

如果你一定要在子组件拿到这个值,不希望直接watch,那换一种思路,不要在data里面定义这个myFormData,你可以试试computed计算这个属性

computed: {
  myFormData: function () { // 记得去掉在data中定义的myFormData
    return this.formData // 这里返回你prop传过来的值
  }
},
watch: { // 在这里watch上面计算属性myFormData
  myFormData (newValue) {
    console.log('我改变了');
  }
}

PS:记得把你的data里面定义的myFormData去掉,上述方法选一个都行

楼主,你好!你 watch 的对象不对吧,应该 watch 父组件传递过来的 formData, 而不是子组件里的 myFromData。可以试试看。

楼上正解!!!!!

formData自己的属性是改变了;
但是对于子组件来说,formData还是原来那个对象,它的内存地址没变:

if (prevProps.formData !== nextProps.formData) {
    // "组件重渲染"
}

尝试修改formData时,通过深拷贝之类的办法再创建一个新对象吧。

刚才解决了,最后发现是我在父组件最开始给fromData属性赋值的时候使用了fromData.X=XXX的形式,导致vue不能监听到这个对象的属性变化,改成this.$set后,使这个对象属性转成了getter和setter后,就可以正常响应了,谢谢大家的帮忙

宣传栏