vue中,data定义的数组是如何实现响应式的,结合实例反映对源码的理解程度。

博客讨论了在处理异步数据时如何确保Vue.js应用中的列表响应式。通过示例代码,解释了错误的异步更新方式会导致工作对象属性无法成为响应式,并提出正确解决方案:使用`Promise.all`等待所有异步请求完成后再更新列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是我项开发中的一个例子。

说明:已知data中定义了List:[],getDownloadRecord、getWorkDetail均是Promise请求,现在发现getDownloadRecord返回的数组A的每条数据属性太少了,现在想在数组A的每条数据上加一个work对象属性,这个对象通过getWorkDetail获取。那么如何保证最后的List数组是响应式的(⊙o⊙)?

答:获取A后,对其遍历用getWorkDetail加work属性,将每次遍历的异步存储下来,通过await Promise.all(arr)等待全部的请求完成,这时候再将A加到this.List.身上:this.List.push(…A)。如果不使用await等待异步完成就去this.List.push(…A),最后this.List.身上的work属性就不是响应式的。因为根据事件循环机制,同步代码先被执行,然后再异步,在同步代码执行过程中已经完成了对List的响应式处理,等到异步拿到结果时,就新来的work属性就错过了成为响应式数据的时机。

错误实例1

    // 获取更多
    async getMore () {
      let res = await getDownloadRecord({
        uuid: this.$store.getters.get_uuid,
        limit: 5,
        page: this.Num++
      })
      if (res.data[0].length === 0) {
        return this.$message({
          type: 'warning',
          message: '数据已经加载完毕!'
        })
      }
      console.log('---this.List-res---', res)
      let arr = []
      res.data[0].forEach(i => {
        getWorkDetail(i.workId).then(res => {
          // 等到this.List.push(...res.data[0])执行完的时候,这里的才开始赋值。
          i.work = res.data
        })
        // arr.push(getWorkDetail(i.workId).then(res => {
        //   i.work = res.data
        // }))
      })
      // await Promise.all(arr)
      console.log('--this.List---res.data[0]-----', res.data[0])
      this.List.push(...res.data[0])
      console.log('--this.List--------', this.List)
    }

错误实例2.

    // 获取更多
    async getMore () {
      let res = await getDownloadRecord({
        uuid: this.$store.getters.get_uuid,
        limit: 5,
        page: this.Num++
      })
      if (res.data[0].length === 0) {
        return this.$message({
          type: 'warning',
          message: '数据已经加载完毕!'
        })
      }
      过早给List“赋值”了
      this.List.push(...res.data[0])
      console.log('---this.List-res---', res)
      let arr = []
      res.data[0].forEach(i => {
        // getWorkDetail(i.workId).then(res => {
        //   i.work = res.data
        // })
        arr.push(getWorkDetail(i.workId).then(res => {
          i.work = res.data
        }))
      })
      await Promise.all(arr)
      console.log('--this.List--------', this.List)
    }

以下代码,是正确的写法:

    // 获取更多
    async getMore () {
      let res = await getDownloadRecord({
        uuid: this.$store.getters.get_uuid,
        limit: 5,
        page: this.Num++
      })
      if (res.data[0].length === 0) {
        return this.$message({
          type: 'warning',
          message: '数据已经加载完毕!'
        })
      }
      console.log('---this.List-res---', res)
      let arr = []
      res.data[0].forEach(i => {
        // getWorkDetail(i.workId).then(res => {
        //   i.work = res.data
        // })
        arr.push(getWorkDetail(i.workId).then(res => {
          i.work = res.data
        }))
      })
      await Promise.all(arr)
      console.log('--this.List---res.data[0]-----', res.data[0])
      this.List.push(...res.data[0])
      console.log('--this.List--------', this.List)
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值