Vue 父组件传值给子组件,对象数组类型,父组件直接调用子组件方法,会是上次的引用地址,vue 父子组件传值数据不能实时更新问题

vue 父子组件传值数据不能实时更新问题

解决方案一: 在子组件进行深度监听,然后监听里调用方法就可以了

父组件测试代码

<WranList ref="myEMChartRef2" :data-arr="dataArr" />



data() {
    return {
      dataArr: ['父组件初始的数据测试dataArr'],
    }
  },



mounted() {
    let ii = 0
    setInterval(() => {
      ii++
      this.dataArr = ['定时器' + ii]
      console.log('父组件改变子组件值,改变后的值为', this.dataArr)
      this.$refs && this.$refs.myEMChartRef2 && this.$refs.myEMChartRef2.reFresh()
    }, 10000);
}

子组件测试代码

props: {
    dataArr: {
      type: Array,
      required: true,
      default: () => {
        return []
      }
    }
  },

  data() {
    return {
      currentDataArr: this.dataArr
    }
  },

  watch: {
    dataArr(val) {
      console.log('子组件深度监听获取的val', val)
      this.currentDataArr = [...val]
      this.reFresh() // 打开这个就可以更新为最新数据了
    }
  },

methods: {
    reFresh() {
      console.log('当前子组件方法里内数据', this.currentDataArr)
    }
}

打印结果


父组件改变子组件值,改变后的值为 ["定时器2", __ob__: Observer]
当前子组件方法里内数据 ["定时器1", __ob__: Observer]
子组件深度监听获取的val ["定时器2", __ob__: Observer]

父组件改变子组件值,改变后的值为 ["定时器3", __ob__: Observer]
当前子组件方法里内数据 ["定时器2", __ob__: Observer]
子组件深度监听获取的val ["定时器3", __ob__: Observer]

父组件改变子组件值,改变后的值为 ["定时器4", __ob__: Observer]
当前子组件方法里内数据 ["定时器3", __ob__: Observer]
子组件深度监听获取的val ["定时器4", __ob__: Observer]

父组件改变子组件值,改变后的值为 ["定时器5", __ob__: Observer]
当前子组件方法里内数据 ["定时器4", __ob__: Observer]
子组件深度监听获取的val ["定时器5", __ob__: Observer]

解决方案二this.$nextTick

let ii = 0
    setInterval(() => {
      ii++
      this.dataArr = ['定时器' + ii]
      console.log('父组件改变子组件值,改变后的值为', this.dataArr)
      this.$nextTick(()=>{this.$refs.myEMChartRef2.reFresh(ii)})
    }, 10000);
    this.changeTiming(200000);


打印结果

父组件改变子组件值,改变后的值为 ["定时器4", __ob__: Observer]
子组件深度监听获取的val ["定时器4", __ob__: Observer]
当前子组件方法里内数据 4 ["定时器4", __ob__: Observer]


父组件改变子组件值,改变后的值为 ["定时器5", __ob__: Observer]
子组件深度监听获取的val ["定时器5", __ob__: Observer]
当前子组件方法里内数据 5 ["定时器5", __ob__: Observer]

需要特别注意的是,如果父组件给子组件传值采用this.$nextTick方式更新,子组件只声明props就可以了,不用再进行重新声明,也不需要进行深度监听

下面就是一个错误的案例

父组件

<WranList ref="myEMChartRef2" :data-arr="dataArr" />


setFunTimeOut(componentName, fun = null) {
      let timeOutFun
      if (this.$refs && this.$refs[componentName]) {
        console.log('存在这个dom')
        if (fun) { fun() } else {
          console.log('存在这个dom---执行刷新函数')
          console.log('执行此函数时候的dataArr', this.dataArr)
          this.$refs[componentName].reFresh()
        }
      } else {
        window.clearTimeout(timeOutFun)
        timeOutFun = setTimeout(() => {
          if (fun) { fun() } else {
            console.log('不-----存在这个dom', this.$refs[componentName])
            this.$refs[componentName].reFresh()
          }
        }, 1000);
      }
    },


// 父组件调用
this.dataArr = res2.List
          console.log('this.dataArr父组件里的值', this.dataArr)
          this.$nextTick(
            () => { this.setFunTimeOut('myEMChartRef2') }
          )

子组件


props: {
    dataArr: {
      type: Array,
      required: true,
      default: () => {
        return []
      }
    }
  },


 data() {
    return {
      currentDataArr: this.dataArr
    }
  },


 methods: {
    reFresh() {
      console.log('当前子组件方法里内数据this.dataArr',  this.dataArr)
      console.log('当前子组件方法里内数据this.currentDataArr',  this.currentDataArr)
    }
}


打印结果

this.dataArr父组件里的值 (1) ['最新新数据', __ob__: Observer]
存在这个dom
存在这个dom---执行刷新函数
执行此函数时候的dataArr (1) ['最新新数据', __ob__: Observer]
当前子组件方法里内数据this.dataArr (1) ['最新新数据', __ob__: Observer]
当前子组件方法里内数据this.currentDataArr ["上一次的数据", __ob__: Observer]

可以看出,子组件props里的数据是更新的,但是重新声明的那个是上一次的数据,假如我们要对子组件进行深度监听,比如加上下面的代码,就可以采用这种方式,但是父组件可以直接更改值,不使用this.$nextTick,但是毕竟耗费性能,所以。。。。。。你懂的

子组件可以加上这个,但是不建议

// watch: { // 暂时决定采用方案二,深度监听太耗费性能
  //   dataArr(val) {
  //     console.log('子组件深度监听获取的val', val)
  //     this.currentDataArr = [...val]
  //     // this.reFresh() // 假如说不用这行代码,子组件就不会更新数据
  //   }
  // }

原文地址:https://www.cnblogs.com/sugartang/p/14663843.html