Day8 完整学习包(Vue 基础 & 响应式)——2026 0320

一、核心知识点(30 分钟吃透)

1. Vue 响应式核心定义

Vue 响应式是「数据驱动视图」的底层机制:当数据(data/props/computed 等)发生变化时,视图会自动、高效更新,无需手动操作 DOM,核心目标是让开发者聚焦数据逻辑,而非 DOM 操作。

2. Vue2 vs Vue3 响应式原理(核心差异)

表格

版本 核心实现 核心 API 优缺点
Vue2 基于 Object.defineProperty() 劫持对象属性的 getter/setter Object.defineProperty() ✅ 兼容性好;❌ 无法监听数组下标 / 长度变化、无法监听新增 / 删除对象属性
Vue3 基于 Proxy 代理整个对象 + Reflect 反射 new Proxy(target, handler) ✅ 监听整个对象、支持数组下标 / 新增属性、拦截操作更全面;❌ 不兼容 IE

3. 响应式核心流程(Vue2 为例,面试高频)

  1. 初始化劫持 :Vue 实例化时,遍历 data 中的所有属性,用 Object.defineProperty() 重写 getter/setter;
  2. 依赖收集:执行模板渲染时,访问 data 属性触发 getter,将当前组件的 Watcher(观察者)收集到 Dep(依赖管理器)中;
  3. 派发更新:当修改 data 属性触发 setter 时,Dep 通知所有收集的 Watcher,Watcher 触发组件重新渲染(diff 算法对比虚拟 DOM,更新真实 DOM)。

二、实战练习:手写 Vue 计数器(40 分钟必练)

案例 1:Vue2 版计数器(选项式 API)

html

预览

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Vue2 响应式计数器</title>
  <!-- 引入Vue2 -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <!-- 响应式数据绑定 -->
    <h2>当前计数:{{ count }}</h2>
    <!-- 绑定事件修改数据,视图自动更新 -->
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
    <button @click="reset">重置</button>
  </div>

  <script>
    new Vue({
      el: '#app',
      // 响应式数据
      data() {
        return {
          count: 0 // 该属性会被Vue劫持getter/setter
        };
      },
      // 方法(修改响应式数据)
      methods: {
        increment() {
          this.count++; // 触发setter,视图自动更新
        },
        decrement() {
          this.count--;
        },
        reset() {
          this.count = 0;
        }
      }
    });
  </script>
</body>
</html>

案例 2:Vue3 版计数器(组合式 API)

html

预览

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Vue3 响应式计数器</title>
  <!-- 引入Vue3 -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <h2>当前计数:{{ count }}</h2>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
    <button @click="reset">重置</button>
  </div>

  <script>
    const { createApp, ref } = Vue;
    createApp({
      // 组合式API:setup是入口
      setup() {
        // 声明响应式数据(基础类型用ref)
        const count = ref(0);
        
        // 定义方法
        const increment = () => {
          count.value++; // ref需通过.value修改值
        };
        const decrement = () => {
          count.value--;
        };
        const reset = () => {
          count.value = 0;
        };

        // 暴露给模板
        return { count, increment, decrement, reset };
      }
    }).mount('#app');
  </script>
</body>
</html>

案例 3:极简模拟 Vue2 响应式(理解核心)

js

复制代码
// 模拟Dep:依赖管理器,收集Watcher
class Dep {
  constructor() {
    this.watchers = []; // 存储依赖的Watcher
  }
  // 收集Watcher
  depend() {
    if (window.target) {
      this.watchers.push(window.target);
    }
  }
  // 通知更新
  notify() {
    this.watchers.forEach(watcher => watcher.update());
  }
}

// 模拟Watcher:观察者,触发更新
class Watcher {
  constructor(cb) {
    this.cb = cb; // 更新视图的回调
    window.target = this; // 标记当前Watcher
    this.cb(); // 执行回调,触发getter收集依赖
    window.target = null;
  }
  // 更新视图
  update() {
    this.cb();
  }
}

// 模拟Vue2响应式劫持
function defineReactive(obj, key, value) {
  const dep = new Dep(); // 每个属性对应一个Dep
  Object.defineProperty(obj, key, {
    get() {
      dep.depend(); // 收集依赖
      return value;
    },
    set(newVal) {
      if (newVal !== value) {
        value = newVal;
        dep.notify(); // 通知更新
      }
    }
  });
}

// 遍历对象,劫持所有属性
function observe(obj) {
  for (let key in obj) {
    defineReactive(obj, key, obj[key]);
  }
}

// 测试
const data = { count: 0 };
observe(data);
// 创建Watcher,模拟视图更新
new Watcher(() => {
  console.log('视图更新:', data.count);
});
data.count++; // 触发setter,输出「视图更新:1」

三、核心面试题 + 标准答案(20 分钟背会)

面试题:Vue 的响应式原理是什么?(Vue2/Vue3 都要答)

标准答案(高级工程师视角,精简且有深度)
1. 核心定义

Vue 响应式是「数据驱动视图」的底层实现,核心逻辑是:劫持数据的读取 / 修改操作,在数据变化时自动触发视图更新,无需手动操作 DOM,是 Vue 区别于原生 JS/jQuery 的核心特性。

2. Vue2 响应式原理
  • 核心实现 :基于 Object.defineProperty() 劫持对象属性的 getter/setter
  • 核心流程
    1. 数据劫持 :Vue 实例化时,遍历 data 中的所有属性,通过 Object.defineProperty() 重写 gettersetter
    2. 依赖收集 :渲染模板时访问 data 属性,触发 getter,将当前组件的 Watcher(观察者)收集到 Dep(依赖管理器)中;
    3. 派发更新 :修改 data 属性触发 setterDep 通知所有收集的 WatcherWatcher 触发组件重新渲染(通过虚拟 DOM diff 算法更新真实 DOM);
  • 局限性 :无法监听数组下标 / 长度变化、无法监听对象新增 / 删除属性(需用 Vue.set/this.$set 补充)。
3. Vue3 响应式原理(面试加分)
  • 核心优化 :抛弃 Object.defineProperty(),改用 Proxy 代理整个对象 + Reflect 反射;
  • 核心优势
    1. 可监听整个对象(而非单个属性),支持对象新增 / 删除属性;
    2. 原生支持数组下标、长度变化的监听;
    3. 拦截操作更全面(支持 get/set/deleteProperty 等 13 种操作);
  • 兼容处理 :Vue3 提供 ref/reactive 等 API 统一响应式声明,ref 用于基础类型(通过 .value 访问),reactive 用于引用类型。
4. 实际开发中的应用(体现工程化思维)
  • Vue2 中修改数组 / 新增对象属性,需用 this.$set(arr, index, val)/this.$set(obj, key, val)
  • Vue3 中优先用 ref 声明基础类型响应式数据,reactive 声明对象 / 数组,避免响应式失效;
  • 避免直接修改 props 数据(单向数据流),通过 emit 通知父组件修改,保证响应式链路完整。

四、错题整理模板(10 分钟完成)

表格

错题类型 错误代码 / 场景 错误原因 正确思路 / 知识点
Vue2 响应式失效 直接给对象新增属性 this.obj.newKey = 1 未用 Vue.set,新增属性未被劫持 this.$set(this.obj, 'newKey', 1)
Vue3 ref 使用错误 模板中写 count.value 忽略模板中 ref 自动解包特性 模板中直接用 {``{ count }},JS 中用 count.value
原理理解偏差 认为 Vue2 能监听数组 push 仅 Vue 对 7 个数组方法做了重写,下标仍不行 Vue2 重写了 push/pop 等 7 种方法,下标修改仍需 $set

总结

  1. 核心考点:Vue2/Vue3 响应式的实现差异、依赖收集 / 派发更新流程、响应式失效的解决方法;
  2. 实战重点 :掌握 $set(Vue2)、ref/reactive(Vue3)的正确用法,避免响应式失效;
  3. 易错点 :Vue2 新增对象属性、修改数组下标导致响应式失效,Vue3 ref 的 .value 使用规则。
相关推荐
FlyWIHTSKY2 小时前
Vue3 单文件中不同的组件
前端·javascript·vue.js
菜鸡儿齐2 小时前
MapReduce-源码学习
大数据·学习·mapreduce
一字白首2 小时前
小程序组件化进阶:从复用到通信的完整指南DAY04
前端·小程序·apache
读忆2 小时前
你是否用过Tailwind CSS?你是在什么情况下使用的呢?
前端·css·经验分享·笔记·taiiwindcss
heanyu2 小时前
STM32学习 1 ----串口通讯--阻塞式收发+支持printf
stm32·嵌入式硬件·学习
阿珊和她的猫2 小时前
探秘小程序:为何拿不到 DOM 相关 API
前端·小程序
東雪木2 小时前
软件设计师考试复习——CPU 结构、流水线、存储体系(主存 / 辅存)
学习·软件设计师复习
FlyWIHTSKY2 小时前
Vue 3 onMounted 中控制同步与异步执行策略
前端·javascript·vue.js
PascalMing2 小时前
告别 Nginx!ASP.NET Core 实现多域名 Vue 静态服务与代理转发
vue.js·nginx·asp.net