Vue知识总结

一、模板语法

  1. 模板语法: {{}}, computed ,watch
  2. 指令
  3. 条件渲染,列表渲染v-if v-for

二、组件

  1. 组件通信: 父子props,子父$emit,兄弟/跨层级 provide/inject, event bus,vuex/pinia
  2. 插槽:
  3. 生命周期

二、核心机制-响应式,双向绑定

核心思想是数据劫持+发布-订阅模式

2.1 原理

2.1.1 Vue 2的响应式原理:基于 Object.defineProperty

Vue 2通过 Object.defineProperty API来劫持数据的读取和设置(getter/setter)。

实现过程主要分为以下几个步骤:

  1. 数据劫持 (Observer)

    • 当一个普通的JavaScript对象被传入Vue实例作为 data 选项时,Vue会遍历此对象的所有属性。
    • 对于每个属性,Vue会使用 Object.defineProperty 重新定义它的 getset 方法。
    • 这样,当读取 (get) 这个属性时,Vue就知道"谁用了这个数据"。
    • 修改 (set) 这个属性时,Vue就能发出通知,告诉那些用到它的地方进行更新。
  2. 依赖收集 (Dep)

    • getter 中,Vue会进行依赖收集
    • 每个被劫持的属性都会拥有自己的一个依赖管理器 (Dep对象)
    • 当视图在渲染计算属性 在计算时,会创建一个Watcher (订阅者)。这个Watcher在求值过程中会触发数据的 getter
    • 此时,Dep 就会把这个当前的 Watcher 添加到自己的订阅者列表里。这就建立了"数据→依赖(Watcher)"的关系。
  3. 派发更新 (Notify)

    • 当数据的值被修改,即触发了 setter 时,Vue会通知对应的 Dep
    • Dep 会遍历它管理的所有 Watcher,并调用它们的 update 方法。
    • Watcherupdate 方法最终会触发组件的重新渲染(re-render)或计算属性的重新计算,从而将最新的数据反映到视图上。

Vue 2实现的局限性:

  • 无法检测对象属性的添加或删除 :由于 Object.defineProperty 是在初始化时遍历属性进行劫持的,所以后续新增的属性不是响应式的(需使用 Vue.set)。
  • 对数组的限制 :无法劫持数组的索引操作(如 arr[index] = newValue)和修改长度的操作(如 arr.length = 0)。Vue通过重写数组的7个变更方法(push, pop, shift, unshift, splice, sort, reverse)来实现数组的响应式。

2.1.2 Vue 3的响应式原理:基于 Proxy

Vue 3使用了ES6的 Proxy 来重写了响应式系统,解决了Vue 2的大部分局限性。

实现过程:

  1. 数据劫持 (Reactive)

    • Vue 3通过 reactive() 函数创建一个对象的响应式代理。
    • Proxy 可以拦截对一个对象任何性质 的操作,包括属性的读取 (get)、设置 (set)、删除 (deleteProperty)、in 操作符等共13种,而不仅仅是 getset
    • 这意味着,无论是已有属性还是新增、删除属性,都能被完美劫持。
  2. 依赖收集与派发更新 (Track/Trigger)

    • track (追踪) :在 Proxyget 拦截中,Vue会执行 track 函数,用于建立"目标对象→属性→依赖"的关系。这里的"依赖"在Vue 3中被称为 effect,类似于Vue 2的 Watcher
    • trigger (触发) :在 ProxysetdeleteProperty 等拦截中,Vue会执行 trigger 函数,它会根据操作的类型和key,找到所有相关的 effect 并执行它们。
  3. Ref

    • 对于原始值(如 number, string),Proxy 无法代理。Vue 3提供了 ref 函数来解决。
    • ref 会创建一个响应式的引用对象(RefImpl 实例),该对象的 .value 属性才是真正的值。访问 .value 时进行依赖收集,修改 .value 时触发更新

一个组件一个渲染 Watcher,不是多个,Dep是多个。 Watcher(订阅者)订阅了 Dep(发布者)。 你修改数据 -> 数据的 Dep (发布者) 发出通知 -> 所有订阅了该Dep的 Watcher (订阅者) 收到通知 -> Watcher 执行更新操作 -> 视图变化

kotlin 复制代码
// 伪代码,在 userInfo.age 的 getter 内部
if (Dep.target) { // Dep.target 就是当前正在执行的 Watcher (渲染 Watcher)
    dep.depend(); // 核心:让 Dep 收集这个 Watcher
}
return value;
scss 复制代码
// 伪代码,在 userInfo.age 的 setter 内部
set(newVal) {
  value = newVal;
  dep.notify(); // 核心:Dep 通知所有订阅者!
}

2.2 虚拟DOM

在 Vue 2 中,响应式系统和虚拟 DOM 是两个独立但协同工作的核心模块,两者共同支撑了 Vue 的数据驱动视图能力。

  • 响应式系统:负责追踪数据变化,当数据更新时通知相关依赖(组件)。
  • 虚拟 DOM:负责将数据变化高效地映射到真实 DOM,是响应式系统触发更新后的 "渲染执行者"。

2.3 模板编译

  • 阶段 1:解析(Parse)------ 模板 → AST
  • 阶段 2 转换(Transform)------ AST → 优化后的 AST
  1. 指令转换

    • v-if 转换为条件判断逻辑(if/else)。
    • v-for 转换为循环逻辑(Array.map)。
    • v-bindv-on 转换为对应的属性绑定和事件监听(如 onClick)。
    • {{ name }} 插值转换为 _ctx.name(访问组件上下文的变量)。
  • 阶段 3 生成(Generate)------ AST → 渲染函数

三、核心机制-组合式api

Vue 组合式 API 的原理是一个有机结合体:

  1. 以响应式系统为引擎refreactive 提供了数据驱动的动力。
  2. setup() 函数为入口和上下文:它创建了组件初始化的执行环境,并收集所有暴露出的状态和方法。
  3. 以生命周期钩子函数为连接器:它们将逻辑与组件的生命周期阶段挂钩。
  4. 以普通 JavaScript 函数为复用载体:通过函数和闭包,将响应式状态和逻辑封装成可复用的单元。

它并没有引入全新的魔法,而是更底层、更灵活地暴露了 Vue 响应式系统的能力,让开发者能够像编写普通 JavaScript 代码一样来组织组件逻辑,从而获得了更好的类型推断、逻辑复用和代码组织能力。

  • 当渲染函数读取到 setup 返回的某个响应式属性(如 count.value)时,就会触发该响应式属性的 getter,从而将这个组件的渲染 effect (可以看作是一个特殊的 Watcher)收集为依赖。这就建立了数据 → 视图的依赖关系。
  1. 虚拟Dom

四、高级特性 vue 2 mixin

Vue 中的 mixin 是一种代码复用机制,用于将多个组件中可复用的逻辑(如数据、方法、生命周期钩子等)提取到一个独立的对象中,然后在多个组件中 "混入" 这些逻辑,实现代码共享。

  1. 合并规则

    • 数据(data):组件自身数据优先级高于 mixin,若存在同名属性,组件数据会覆盖 mixin
    • 方法、计算属性:同名时,组件自身的会覆盖 mixin 的。
    • 生命周期钩子:mixin 中的钩子会比组件自身的同名钩子先执行(如 mixincreated 先于组件的 created 执行)。
    • 组件选项(如 componentsdirectives):会合并为一个对象,同名键会被组件自身覆盖。
  • 缺点

    1. 命名冲突风险:mixin 与组件、mixin 之间可能出现同名属性 / 方法,不易排查。

    2. 逻辑来源模糊:组件中使用的属性或方法可能来自多个 mixin,调试时难以追溯。

    3. 灵活性有限:无法向 mixin 传递参数,难以实现个性化逻辑。

    Vue 3 中推荐使用 组合式 API(setup 函数 + 自定义 Hooks) 替代 mixin,通过函数调用的方式复用逻辑,解决了 mixin 的命名冲突和来源模糊问题,更适合复杂场景。

五、keep alive

  1. 缓存机制
    <keep-alive> 会将包裹的组件实例缓存到一个内部对象(通常称为 cache)中,键值一般是组件的 name 或标签名。当组件需要被切换(如使用 <router-view>v-if)时,不会执行 beforeDestroydestroyed 生命周期,而是被缓存起来。

  2. 激活与失活

    • 被缓存的组件再次渲染时,不会执行 createdmounted 等初始化生命周期,而是触发 activated 钩子。
    • 组件被缓存隐藏时,不会销毁,而是触发 deactivated 钩子。
  3. DOM处理
    <keep-alive> 自身不会渲染 DOM 节点,也不会出现在组件的父链中。它会将缓存的组件实例保存在内存中,对应的 DOM 节点会被暂时移除或隐藏,重新激活时再插入到文档中。

    • activated 是 Vue 的特殊生命周期钩子 ,需要与 <keep-alive> 配合使用

为什么不会重新渲染?

Vue 的组件生命周期在首次加载 Tab2 时会正常执行:created -> mounted -> ...。

当你切换到 Tab1 时,Tab2 会执行 deactivated

当你再次切换回 Tab2 时,Vue 会直接从缓存中恢复它的整个实例(包括所有的数据、DOM状态),因此只会触发 activated 钩子,而不会再次触发 createdmounted

六、路由管理

vue-router

七、状态管理Pinia/Vuex

组件 -> Dispatch Action -> Commit Mutation -> Modify State 组件 -> Call Action -> Directly Modify State组件 -> Directly Modify State

其他、React Vue对比

react vue 有哪些功能是对方没有的?

  1. React 并发渲染 可中断 useTransition
  2. vue 双向绑定、类html模板语法指令系统
相关推荐
To_OC1 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic2 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy2 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志2 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble3 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯4 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜5 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森6 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒6 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端