MST

星途 面试题库

面试题:Vue监听对象深层次变化的原理及实现

假设有一个复杂对象:data: { person: { name: 'John', age: 30, hobbies: ['reading', 'traveling'] } },解释Vue是如何实现对该对象及其嵌套属性的变化监听的,并且用代码展示如何使用watch精确监听'hobbies'数组的变化,即使'hobbies'数组内部元素顺序改变也能监听到。
50.2万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

Vue对复杂对象及其嵌套属性变化监听的原理

Vue 使用 Object.defineProperty() 方法来进行数据劫持,为对象的每个属性定义 getter 和 setter。对于嵌套对象,Vue 会递归地将其所有属性都进行数据劫持。在 Vue 2.x 中,由于 JavaScript 的限制,对于对象新增属性或删除属性,Vue 无法自动监听,需要使用 Vue.set$set 方法来触发响应式更新。对于数组,Vue 重写了数组的原型方法(如 pushpopshiftunshiftsplicesortreverse),当调用这些方法时会触发视图更新。

代码展示精确监听 'hobbies' 数组变化

<template>
  <div>
    <button @click="addHobby">添加爱好</button>
    <button @click="changeHobbyOrder">改变爱好顺序</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: {
        person: {
          name: 'John',
          age: 30,
          hobbies: ['reading', 'traveling']
        }
      }
    };
  },
  watch: {
    'data.person.hobbies': {
      handler(newVal, oldVal) {
        console.log('hobbies 数组变化了', newVal, oldVal);
      },
      deep: true
    }
  },
  methods: {
    addHobby() {
      this.data.person.hobbies.push('coding');
    },
    changeHobbyOrder() {
      this.data.person.hobbies.reverse();
    }
  }
};
</script>

在上述代码中,通过在 watch 中设置 deep: true 来深度监听 hobbies 数组的变化,这样即使数组内部元素顺序改变也能监听到。handler 函数中的 newValoldVal 分别代表变化后的数组和变化前的数组。