Vue核心理解

谈谈对Vue的理解?

背景层:为了解决数据绑定+组件化的需求而研发出来的。


技术层:

响应式内核:数据即状态,状态即视图

组件化:模版+脚本+样式三合一,编译时静态提升

静态提升:把不含响应式的dom抽成常量

tree-shaking:未用到的组件/指令/函数工具包不进行打包

渐进式生态:路由、状态、构建、桌面端、移动端


3.x质变:

组合式api+原生ts支持

性能:响应式原理重写,ssr性能提升,包体积减小


前景分析:

3.x+vite+pinia结合,已成为国内"默认栈"

存量巨大:全国大部分中小型企业+外包+存量项目都在使用vue2/vue3

uniapp跨端需求大,实现一码多端

Vue的设计理念?

更好的开发体验:组合式API、更好的支持TS

性能提升:编译时静态提升、响应式优化、虚拟dom重写+tree-shaking打包优化

Vue2与Vue3

Vue2和Vue3的区别在于什么地方?

1. vue3性能翻倍(响应式区别:vue2初始化即遍历全部属性,vue3访问才代理)

打包体积更小(v3全部模块化,gzip下降41%)

2. 原生ts支持

3. 组合式api

4. 打包工具(webpack/vite),构建速度更快,浏览器ESModule模块秒级热更新

Webpack和Vite区别?

编译区别:

webpack:全量编译(webpack-dev-server-HMR runtime),全部打包再服务

vite:按需编译,只编译当前请求的文件(浏览器ESModule模块热替换),不打包直接服务


打包区别:

webpack:自研webpack

vite:rollup+esbuild预构建依赖

响应式系统

Vue3中的ref和reactive区别?

ref为原子响应式,访问和更改需要.value,常用于基本数据类型

reactive为深层响应式对象,直接访问和修改不需要.value,常用于对象/数组类型

根替换ref可以直接更改,reactive则需要Object.assign()方式替换才能变成响应式,因为后者会生成新的对象,响应式丢失

Vue响应式完整逻辑?

v3通过调用reactive和ref方法创建响应式变量,reactive使用了new Proxy()的get和set的陷阱方法来进行依赖追踪和数据拦截,ref是通过对象访问器的get和set方法来进行依赖追踪和数据拦截。


v2是通过Object.defineProperty的getter和setter方法进行依赖追踪和数据拦截。


数据改变 → Set调用(数据拦截) → trigger调用(触发依赖更新) → EffectFnItem.scheduler调用 → queueJob() → queueFlush调用(等待执行微任务) → 等待同步任务全部执行完 → 微任务调用任务队列对象的run方法 → run方法内调用组件更新函数componentUpdateFn(1.通过instance.render方法来生成新的虚拟dom 2.调用diff方法计算最小差异 3.通过patch方法最小化更新真实dom) → 页面更新响应式完成


Vue2 通过 Object.defineProperty 深度递归劫持已存在属性,

无法自动监听新增、删除、数组索引变化(需 Vue.set / Vue.delete 补丁);

闭包强引用每个属性值,大对象内存难释放。


Vue3 通过 Proxy + WeakMap 懒代理整个对象,

全语言特性拦截,weakmap弱引用依赖表,对象被GC时内存自动释放


v3优点:拦截更全,访问时才代理,大对象启动快 + 运行时性能更高,内存不泄漏

Vue3响应式核心API?

ref、reactive、

computed计算属性、

watchEffect立即执行侦听器、watch(单个、多个、深度监听)、

readonly只读、

shallowRef:只对.value触发更新

shallowReactive:只对第一层响应式触发更新

markRaw:标记为非响应式。被改变时不会触发更新

toRaw:获取原始对象,把对象改为非响应式,相当于markRaw

customRef:自定义ref

triggerRef:强制触发更新

核心API

Watch和Computed的区别?

watch:关注变化,回调函数拿到新旧值,不需要返回值。场景:关注的数据发生变化执行某些操作。

Computed:关注结果,需要用到什么哪些变量生成一个新的计算结果,需要返回值。场景:通过对别的变量计算得到一个新的计算结果。

Diff算法的作用?核心原理是什么?

作用:最小化操作dom,保持状态正确

原理:同级对比+头尾双指针对比+key哈希表扫剩余

组件通信

Vue3组件传递参数?

props:父传子

emits:子传父

mitt/bus:兄弟传参

provide/inject:跨组件传参,不需要逐层传递props

mitt和event bus区别?

mitt:纯js,不依赖框架、支持ts、兼容vue3、轻量级包 大约200字节

event bus:依赖vue实例、ts支持一般、不兼容vue3、包大小需要整个vue

什么是mixin?

把可复用的功能混合到组件中,多组件混合使用同一个功能。

路由与状态管理

Vue的路由模式有哪些?什么是路由守卫?

路由模式:hash模式和history模式(美观、404需要服务器做路由重定向index.html)

路由守卫:beforeEach、beforeEnter、beforeRouterEnter、afterEach

Vuex和Pinia的区别?

共同属性:state,getter,mutations(同步),actions(异步)


vuex:需要有一个主文件的createStore里面的modules管理多模块,再把这个主文件通过app.use(store)挂载。


pinia:每个模块是独立的,对应组件需要用到才引入。按需引入有利于tree-shaking打包。


特性 Vuex Pinia

Vue 版本 Vue 2/3 Vue 3

API 风格 选项式 选项式 + 组合式

TypeScript 需要类型定义 原生支持

模块系统 命名空间模块 多个 Store

大小 ~10KB ~1KB

响应式 基于 Vue 响应式 基于 Vue 3 reactive/ref