❓Vue的响应式原理是什么?
Vue2 的 Object.defineProperty
- Vue2 使用
Object.defineProperty
方法为对象属性添加get
和set
拦截器,以监听数据的变更。对于多层嵌套对象,会通过递归处理实现深度监听。- 缺点:某些场景下,数据变更无法被检测到,如新增或删除属性,以及数组索引操作。
- 局限性:不支持
Map
和Set
数据结构。
Vue3 的 Proxy
- Vue3 中使用 ES6 的
Proxy
对象,可以一次性代理整个对象,对get
和set
进行拦截,避免逐个属性设置的复杂性,提升性能并节省内存。- 缺点:
Proxy
不兼容 IE 浏览器。 - 实现原理:Vue 的响应式基于观察者模式,而事件机制(
on/emit
)基于发布订阅模式。
- 缺点:
❓Vue3 有哪些新特性?
- 组合式 API:
Composition API
以及setup
语法糖,使得代码组织更加内聚,逻辑复用更容易,不再像Options API
那样分散在各个选项中。 - 响应式性能提升:采用
Proxy
实现响应式。 - 引入 Tree-shaking:减少打包体积。
- 全面支持 TypeScript:更好的类型支持。
- Monorepo:项目结构更清晰,管理更方便。
❓什么是虚拟 DOM 和 Diff 算法?
-
虚拟 DOM:是 JavaScript 模拟的 DOM 树结构,目的是为了提高页面 DOM 操作的性能。
- 优势:大量频繁的 DOM 操作可能导致页面回流和重绘,造成卡顿。虚拟 DOM 可以在内存中完成大部分操作,最后一次性更新到真实 DOM。
-
Diff 算法:当数据变化时,首先更新虚拟 DOM,然后通过 Diff 算法计算出新旧虚拟 DOM 之间的差异,并批量更新到真实 DOM。
- Key 的作用:
key
是虚拟 DOM 节点的唯一标识,在 Diff 算法中可以更快地找到对应节点、复用节点,减少 DOM 操作,提升性能。
- Key 的作用:
❓模板编译的原理?
Vue2 的编译过程:
- parse:解析模板,生成抽象语法树(AST)。
- optimize:优化 AST,标记静态节点。
- generate:生成渲染函数
render
。
Vue3 的编译过程:
- parse:解析模板,生成抽象语法树(AST)。
- transform:遍历 AST 进行转换。
- generate:生成渲染函数
render
。
❓nextTick(callback)
的原理?
Vue 采用异步更新策略,数据变化后不会立即更新 DOM,而是将更新操作缓存到一个队列中,最后批量更新 DOM 并进行渲染。nextTick
的回调函数会在下一次 DOM 更新后执行,其内部基于 Promise 的微任务队列实现。执行顺序为:执行一个宏任务 -> 清空微任务 -> 渲染。
❓组件有哪些通信方式?
- 父子组件通信:通过
props
向下传递数据,通过$emit
事件向上传递数据。 - 引用和实例:通过
$refs
、$parent
、$root
、$children
来访问组件实例。 - 全局状态管理:使用 Vuex 管理全局状态。
❓Vue 的生命周期?
选项式 API | 组合式 API | 备注/使用 |
---|---|---|
beforeCreate | 不需要(直接写到 setup 函数中) | |
created | 不需要(直接写到 setup 函数中) | 发送 Ajax 请求,挂载资源 |
beforeMount | onBeforeMount | |
mounted | onMounted | 发送 Ajax 请求,依赖于 DOM 的业务 |
beforeUpdate | onBeforeUpdate | |
updated | onUpdated | |
beforeDestroy | onBeforeUnmount | |
destroyed | onUnmounted | 销毁操作,如清理定时器 |
activated | onActivated | |
deactivated | onDeactivated | 在 keep-alive 中使用的钩子 |
❓v-if
/ v-show
/ v-for
v-if
:条件成立才会渲染当前节点,适用于在某些情况下需要动态创建和销毁 DOM 元素的场景。v-show
:条件成立元素显示(通过display:none
控制),适用于频繁切换显示状态的元素。v-for
:循环渲染节点,建议使用key
提升性能。在 Vue2 中,v-for
优先级高于v-if
;而在 Vue3 中,v-if
优先级更高,建议通过计算属性来过滤列表数据,避免性能问题。
❓Vue 的计算属性 computed
是什么原理?如何实现自动更新的?
computed
属性会根据它所依赖的 data
数据自动更新。这是因为 Vue 内部在 computed
首次使用时,会收集其依赖的属性。当依赖属性发生变化时,会重新计算 computed
的值。
❓Vue 的 CSS 作用域(scoped
)是怎么实现的?
每个 Vue 文件会生成一个唯一的 id
,HTML 标签上会带有这个 id
属性,CSS 选择器也会加上这个 id
值作为属性选择器,从而实现 CSS 的定向作用域。
❓Vue 的单文件组件(SFC)与 Loader
单文件组件(SFC, Single File Component)是 Vue 中常用的组件编写方式,使用 <template>
、<script>
和 <style>
标签将组件的结构、逻辑和样式分离。Webpack 打包时会使用 vue-loader
来处理这些代码块。
❓Vuex 的原理
Vuex 的核心是它的 state
数据,作为一个公共的数据状态仓库,通过混入方式在 beforeCreate
钩子中将 $store
挂载到每个 Vue 实例上。
- 响应式实现:
$store
的state
类似于 Vue 的data
,同样实现了响应式。当页面使用了$store
的数据时,Vue 会收集数据的依赖关系,在数据变更时自动通知相关组件更新。
❓Vue Router 的前端路由原理
单页应用依赖于前端路由,浏览器中实际上只有一个页面文档,前端通过监听 URL 地址的变化,动态更新页面内容。Vue Router 支持两种模式:
-
Hash 模式:使用 URL 中的
#
后面的哈希值进行路由。浏览器不会将哈希值发送到服务器,因此可以通过hashchange
事件监听哈希值的变化。 -
History 模式:基于
window.history
提供的pushState()
和replaceState()
方法,更新浏览历史记录和 URL 地址,而不会刷新页面。通过popstate
事件监听 URL 的变化。
❓Vue 中的自定义指令
- 定义:Vue 允许开发者创建自定义指令来直接操作 DOM 元素。例如,在
mounted
阶段对元素进行某种操作。 - 使用:
- 全局自定义指令:使用
Vue.directive
注册。 - 局部自定义指令:在组件的
directives
选项中注册。
- 全局自定义指令:使用
- 生命周期钩子:
bind
:指令第一次绑定到元素时调用。inserted
:元素插入父节点时调用。update
:组件更新时调用,但可能会发生在其子 VNode 更新之前。componentUpdated
:组件的 VNode 更新时调用。unbind
:指令从元素解绑时调用。
❓Vue 中的过渡与动画
-
基础过渡:使用
transition
组件为元素切换状态(显示/隐藏)时添加过渡效果。- 支持单个元素的过渡:
v-if
、v-show
。 - 支持列表过渡:使用
transition-group
组件。
- 支持单个元素的过渡:
-
动画:Vue 支持 CSS 动画和 JavaScript 钩子函数,可以在元素进入、离开、更新等过程中添加动画效果。
❓Render 函数和 JSX
- Render 函数:Vue 允许使用
render
函数代替模板来描述组件的结构。这在需要动态生成复杂的 DOM 结构时非常有用。 - JSX 支持:Vue 通过 Babel 插件支持 JSX 语法,使得编写 Render 函数时可以更接近 HTML 模板语法。
❓Vue 组件的高级特性
- 异步组件:通过
defineAsyncComponent
函数定义异步组件,优化首屏加载时间。 - 函数式组件:使用
functional
选项创建无状态且没有实例的轻量级组件。 - 插槽(Slots):
- 默认插槽:父组件在使用子组件时可以传递默认内容。
- 具名插槽:通过
name
属性传递多个插槽。 - 作用域插槽:子组件将数据通过插槽传递给父组件进行渲染。
❓Vue 的混入(Mixins)
- 定义:混入是 Vue 复用组件逻辑的一种方式,可以将复用的逻辑提取到 mixin 中,然后在组件中混入。
- 缺点:混入可能导致命名冲突和代码难以理解。Vue3 推荐使用
Composition API
替代混入。
❓性能优化
- 懒加载:通过路由懒加载和异步组件,减少首屏加载时间。
- 长列表性能优化:使用
v-for
渲染长列表时,可以结合virtual-scroller
或keep-alive
实现懒加载和缓存。 - 减少重绘和回流:避免频繁的 DOM 操作,使用
nextTick
来批量处理。 - 预编译模板:将 Vue 模板预编译为 Render 函数,减少运行时的开销。
❓Vue3 的 Composition API 与 Options API 对比
- 灵活性:
Composition API
提供了更灵活的代码组织方式,可以更好地复用逻辑和维护复杂的组件。 - 代码复用:
Composition API
中的逻辑可以更轻松地抽离为独立的函数,方便复用和测试。 - 兼容性:
Composition API
可以与Options API
一起使用,方便老项目的迁移。
❓Vue DevTools 和调试
- Vue DevTools:强大的浏览器扩展,用于实时调试 Vue 应用,查看组件树、状态、路由等。
- 调试技巧:可以通过
console.log
、debugger
、Vue DevTools 等方式调试组件的生命周期、状态变化等。
❓服务端渲染(SSR)
- SSR 概述:服务端渲染指在服务端生成 HTML 内容,减少客户端渲染的时间,提升首屏加载速度和 SEO 效果。
- Nuxt.js:基于 Vue 的服务端渲染框架,提供了开箱即用的 SSR 解决方案。
❓Vue3 新增特性:Teleport
- Teleport:
Teleport
组件允许你将子组件渲染到 DOM 树中的其他位置,而不受父组件的约束。这在实现模态框、工具提示等场景中非常有用。