Skip to content

Vue数组中出现__ob__Observer导致无法取值的问题分析 ​

问题背景 ​

在Vue项目中调用接口时,我们经常需要将接口返回的list数据赋值给data中预定义的数组。但在使用push方法向data中的数组添加数据时,发现无法正常获取数组中的数据,尽管在控制台可以看到数据存在。

问题分析 ​

  1. 常见的处理方案:

    • JSON.parse(JSON.stringify(this.list))
    • Object.assign({}, this.list)

    这些方法本质上是浅拷贝,虽然可以暂时移除Vue的响应式监听,但重新赋值给data中的数组时,监听会重新添加。

  2. 通过示例代码验证:

js
new Vue({
  data: {
    message: 'Hello Vue!',
    arr: [],
    arrtt: ''
  },
  mounted() {
    this.pushArr()
    this.arrforeach()
  },
  methods: {
    pushArr() {
      this.arr.push(
        { name: 11, age: 18 }, 
        { name: 22, age: 25 }
      )
      console.log(this.arr)
    },
    arrforeach() {
      this.arr.filter(item => {
        console.log(item)
        if (item.age == 18) {
          this.arrtt = item.name
          console.warn(this.arrtt)
        }
      })
    }
  }
}).$mount('#app')

关键发现 ​

  1. push操作后可以正常操作数组并获取值
  2. data中的数组在赋值操作后都会出现__ob__Observer标记
  3. __ob__Observer本身不会影响数组的正常操作
  4. 实际问题源于异步操作的时序问题

解决方案 ​

在需要连续调用两个接口,且第二个接口依赖第一个接口返回数据的场景下:

  1. 使用async/await(如果项目支持)
  2. 使用setTimeout延时处理
  3. 在第一个接口的回调中嵌套调用第二个接口

最佳实践 ​

推荐使用第三种方案,即回调嵌套的方式:

js
// 示例代码
api1().then(res => {
  this.list = res.data
  // 在确保数据已经获取后再调用第二个接口
  api2(this.list[0].id)
})

总结 ​

这个问题本质上不是由__ob__Observer造成的,而是异步操作的时序问题。在处理接口调用时,需要确保数据已经正确获取并赋值后再进行后续操作。