know

vue基础

高优先级知识点,需要熟练掌握。

# 1. 能不能两个修饰符,比如 click.self.stop? 可以的

<div class="out-box" @click.stop.prevent="clickEvent(2)" ></div>

# 2. .camel 由于 HTML 特性是不区分大小写的, .camel 修饰符允许在使用 DOM 模板时将 v-bind 属性名称驼峰化,例如 SVG 的 viewBox 属性:实际会被渲染为 viewbox

<svg :viewBox.camel="viewBox"></svg>

# 3. .passive 修饰符主要用于给 onscroll 事件加一个类似.lazy 的修饰符。 在 pc 端是没啥问题的,但是在移动端,会让我们的网页变卡。因此我们要这么使用。

<div @scroll.passive="onScroll">...</div>

# 4. keyCode 修饰符

//普通键
.enter
.tab //<input @keydown.tab="handleTab"> 监听 Tab 键按下
.delete //<input @keyup.delete="handleDelete"> 监听 Delete 键松开
.backspace //<input @keydown.backspace="handleBackspace"> 监听 Backspace 键按下
.space
.esc   //<input @keyup.esc="handleEsc"> 监听 Esc 键松开
.up
.down
.left
.right
//系统修饰键
.ctrl //	<input @keyup.ctrl.enter="submitForm"> 监听 Ctrl + Enter 组合键
.alt  // <button @click.alt="openMenu"> 监听 Alt 键按下并点击
.shift // <input @keyup.shift.enter="submitForm"> 监听 Shift + Enter 组合键
.meta //<input @keyup.meta.c="copy"> 监听 Windows/Command + C 组合键

// 非普通键
v-on:keyup.f1

# 5. 鼠标事件

click.left
click.right
click.middle

# 6. prevent 修饰符的作用是阻止默认事件(例如 a 标签的跳转)

<a href="http://www.w3school.com.cn" @click.prevent="clickEvent(1)">点击A标签</a>

# 7. self 修饰符作用是,只有点击事件绑定的本身才会触发事件。

<div class="out-box" @click.self="clickEvent(2)" >
    触发输出2
    <div class="in-box" @click="clickEvent(1)">触发输出1</div>
</div>

# 8. 事件冒泡默认是由里往外冒泡,capture 修饰符的作用是反过来,由外往内捕获。

<div class="out-box" @click.capture="clickEvent(2)" >
 触发输出2
 <div class="in-box" @click="clickEvent(1)">触发输出1</div>
</div>


点击‘触发输出1’先输出2,再输出1

# 9. lazy 修饰符作用是,改变输入框的值时绑定的 lazyValue 不会改变,当光标离开输入框时,v-model 绑定的值 lazyValue 才会改变

<input type="text" v-model.lazy="lazyValue">

1:vue 基础(41 道题)

2:248 个知识点 地址 (opens new window)

3:Vue 最全知识点 地址 (opens new window)

4:vue 高频

地址 (opens new window)

5:vue 缓存及路由和生命周期触发的完整流程

地址 (opens new window)

Vue3 源码 (opens new window)

# 10. 说说你对 Vue 中异步组件的理解

在 Vue 中,异步组件是指那些在需要时才加载的组件,而不是在应用初始化时就立即加载。这种机制可以显著提升页面加载速度和用户体验,尤其是在大型单页应用(SPA)中,通过懒加载的方式按需加载组件,避免不必要的资源浪费。

  • 减少初始加载时间
  • 按需加载组件
  • 优化用户体验

# 10.1. 使用 defineAsyncComponent

const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'))

# 10.2. 使用 import() 动态导入

Vue 也支持通过 JavaScript 的 import() 动态导入语法来实现异步组件加载。

const AsyncComponent = () => import('./MyComponent.vue')

# 10.3. 异步组件的配合加载状态

const AsyncComponent = defineAsyncComponent({
  loader: () => import('./components/MyComponent.vue'),
  loadingComponent: Loading, // 加载中的组件
  errorComponent: ErrorComponent, // 错误组件
  delay: 200, // 延迟 200ms 显示加载状态
  timeout: 3000 // 超过 3 秒显示错误组件
})

# 11. Vue 有了数据响应式,为何还要 diff ?

Vue 的数据响应式系统和虚拟 DOM + Diff 算法是紧密协作的:

# 11.1. 数据响应式:保证了数据和视图的同步更新,提供了便捷的开发方式。

# 11.2. 虚拟 DOM + Diff 算法:提高了页面渲染的效率和性能,减少了不必要的 DOM 操作,确保了页面的流畅性和响应性。

# 12. vue3 为什么不需要时间分片?

Vue 3 引入了一个全新的编译器,能够生成更高效的渲染函数。这个编译器在编译过程中进行了一系列优化,例如:

# 12.1. 编译器优化

# 12.1.1. 静态提升:将不变的节点提升为常量,只在初次渲染时计算一次。

# 12.1.2. 预字符串化:将静态内容直接转化为字符串,减少了运行时的开销。

# 12.1.3. 缓存事件处理程序:避免了不必要的重新绑定。

# 12.2. 响应式系统的改进

# 12.3. 虚拟 DOM 和 Diff 算法的优化

# 12.4. 单次异步队列

Vue 3 的更新机制基于单次异步队列(single asynchronous queue),它确保在同一事件循环中只进行一次批量更新。再加上现代浏览器的性能提升,使得 Vue 3 能够在大多数情况下提供流畅的用户体验,而无需借助时间分片等复杂的技术。

# 12.5. 自动批处理

# 12.6. 现代浏览器的性能

# 13. vue3 为什么要引入 Composition API ?

  1. 更好的代码组织和重用 Composition API,可以将相关功能的逻辑组织在一起,从而提高代码的可读性和可维护性。
  2. 好的逻辑复用 解决 mixins 的命名冲突和代码可读性差
  3. 更好的 TypeScript 支持
  4. 适应函数式编程趋势

# 14. 谈谈 Vue 事件机制,并手写$on、$off、$emit、$once

Vue 的事件机制允许组件之间进行通信,通过 $on、$off、$emit 和 $once 等方法进行事件的订阅、取消订阅、触发和一次性订阅。

class EventEmitter {
  constructor() {
    this.events = {}
  }

  // 监听事件
  $on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = []
    }
    this.events[event].push(callback)
  }

  // 停止监听事件
  $off(event, callback) {
    if (!this.events[event]) return

    if (!callback) {
      // 如果没有传递 callback,移除所有事件监听
      this.events[event] = []
    } else {
      // 移除特定的事件监听
      this.events[event] = this.events[event].filter(cb => cb !== callback)
    }
  }

  // 触发事件
  $emit(event, ...args) {
    if (this.events[event]) {
      this.events[event].forEach(callback => callback.apply(this, args))
    }
  }

  // 只监听一次事件
  $once(event, callback) {
    const wrapper = (...args) => {
      callback.apply(this, args)
      this.$off(event, wrapper)
    }
    this.$on(event, wrapper)
  }
}

// 示例
const eventBus = new EventEmitter()

// 监听事件
eventBus.$on('test', msg => console.log('test event:', msg))

// 触发事件
eventBus.$emit('test', 'Hello, World!')

// 监听一次事件
eventBus.$once('once', msg => console.log('once event:', msg))

// 触发一次性事件
eventBus.$emit('once', 'This should appear once')
eventBus.$emit('once', 'This should not appear')

// 停止监听事件
eventBus.$off('test')

// 触发事件(已经移除监听)
eventBus.$emit('test', 'This should not appear')

# 15. computed 计算值为什么还可以依赖另外一个 computed 计算值?

computed 计算属性本质上是具有缓存功能的特殊方法。它们只有在其依赖的响应式属性发生变化时才会重新计算,否则返回缓存的值。

  1. 依赖收集
  2. 缓存机制
  3. 更新机制

# 16. 怎么在 Vue 中定义全局方法?

  1. Vue 2.x 中,我们可以通过 Vue.prototype 添加全局方法
  2. Vue 3.x 中,app.config.globalProperties

# 17. 为什么 react 需要 fiber 架构,而 Vue 却不需要?

  1. React 引入 Fiber 架构的主要原因是为了实现更好的异步渲染和更高效的任务调度。Fiber 架构使得 React 能够更细粒度地控制和中断渲染过程,以便更好地响应用户交互、实现懒加载等功能。
  2. Vue 在设计上采用了一种不同的响应式系统和渲染机制,不需要像 React 那样进行复杂的中断和任务调度。Vue 的设计目标可能更注重简洁性和开发体验,而 React 的目标之一是提供更灵活和强大的性能优化工具。

# 18. 如何打破 scope 对样式隔离的限制?

  1. 使用全局样式
  2. 类名继承
  3. 多层级样式嵌套
  4. 使用 /deep/ 或 ::v-deep:

# 19. vue 中怎么实现样式隔离?

  1. 作用域样式(Scoped Styles)
  2. CSS Modules
  3. CSS-in-Js

# 20. Vue 是怎么把 template 模版编译成 render 函数的?

Vue 的模板编译过程主要分为三个步骤:

  1. 解析模板:将模板解析成 AST(Abstract Syntax Tree)
  2. 优化 AST:对 AST 进行优化,比如静态根节点、静态类、静态样式等进行优化
  3. 生成渲染函数:将 AST 转化成渲染函数
  4. 渲染虚拟 DOM当执行渲染函数时,它将生成一个新的虚拟 DOM 树。如果之前已经存在真实的 DOM 树,Vue 将通过比较新旧 VNode 来计算最小的更新操作并应用在真实 DOM 上,从而进行局部更新,提高效率。
  5. 生成 DOM:最后,Vue 将根据最新的 VNode 生成真实的 DOM 元素,并将其插入到页面中,完成渲染。

# 21. Vue 的生命周期有哪些?

  1. beforeCreate:实例被创建,数据观测和事件配置之前
  2. created:实例创建完成,数据观测和事件配置之后
  3. beforeMount:实例开始挂载
  4. mounted:实例挂载完成
  5. beforeUpdate:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前
  6. updated:数据更新完成,DOM 更新之前
  7. beforeDestroy:实例销毁之前调用
  8. destroyed:实例销毁完成
  9. activated:keep-alive 组件激活时调用
  10. deactivated:keep-alive 组件停用时调用

# 22. 说说 Vuex 的原理

受到了 Flux 和 Redux 的影响

  1. State(状态)
  2. Getters(获取器)
  3. Mutations(变更器)
  4. Actions(动作)
  5. Module(模块)

# 23. vue 的响应式开发比命令式有哪些优势?

  1. 简化代码
  2. 提高可读性
  3. 增强用户体验
  4. 降低耦合度

# 24. React 和 Vue 在技术层面有哪些区别?

  1. 视图层:React 使用 JSX 语法,Vue 使用模板语法。
  2. 组件化:React 组件化思想更加简单,Vue 组件化思想更加复杂。
  3. 生命周期不同:React 组件的生命周期分为三个阶段:初始化、更新和卸载。Vue 组件的生命周期分为八个阶段:创建、挂载、更新、销毁等。
  4. 状态管理:React 状态管理使用 Redux,Vue 状态管理使用 Vuex。
  5. 数据驱动方式不同:React 使用单向数据流来管理数据,即从父组件到子组件的传递,所以 React 中组件之间的数据交互相对更加复杂。Vue 则使用双向数据绑定来管理数据,使得组件之间的数据交互更加简洁。

# 25. 单页应用如何提高加载速度?

  1. 代码分割:将代码拆分为小块,按需加载,减少加载时间。
  2. 缓存资源:利用浏览器缓存重复使用的文件,如 CSS、JS、图片等。
  3. 预加载关键资源:提前加载首页所需的关键资源,如 JS、CSS 或数据。
  4. 图片格式优化:选择合适的图片格式,压缩文件大小,使用字体文件代替小图标。
  5. Gzip 压缩:使用 Gzip 压缩减少文件大小,提高传输效率。
  6. CDN 使用:通过 CDN 缓存和传递文件,加快下载速度和提高可靠性。
  7. API 请求优化:减少 API 调用次数,使用缓存和延迟加载技术优化 API 效率。
  8. 服务器端渲染:使用 SSR 生成 HTML,减少客户端渲染时间,但可能增加服务器负担。

# 26. 说说 Vue 中 CSS scoped 的原理

vue-loader(或 Vite 的 @vitejs/plugin-vue)解析到 <style scoped> 时,会给当前组件计算出一个形如 data-v-7ba5bd90 的稳定 hash 属性名。

简言之,scoped CSS 并没有黑科技,只是借助属性选择器 + 编译期自动重写把“全局”变成了“局部”。

# 27. Vue 模板是如何编译的

Vue3:baseCompile() -> compile() -> generate()

  1. 模板解析:通过正则等方式提取出 模板里的标签元素、属性、变量等信息,并解析成抽象语法树 AST
  2. 优化:遍历 AST 找出其中的静态节点和静态根节点,并添加标记
  3. 代码生成:根据 AST 生成渲染函数 render

# 28. vue 中 $route 和 $router 有什么区别?

  1. $route 对象包含当前路由的信息,包括路径、参数、查询字符串、路由名称等。
  2. $router:提供操作路由的方法,控制路由导航。

# 29. 说说 vue3 中的响应式设计原理

Vue3 的响应式 = Proxy 做数据劫持 + WeakMap 做依赖收集/清理 + Effect 做副作用追踪 + 位运算标记追踪类型,最终把「数据变更」映射到「副作用函数重新执行」。

# 30. Vue2.0 为什么不能检查数组的变化,该怎么解决?

this.$set(this.list, index, value)

# 31. Vue3 的 computed 怎么实现的缓存

Vue3 的 computed 通过 dirty 标志 + 惰性求值 + 双向依赖图 + 调度器 实现缓存:

export class ComputedRefImpl<T> {
  public dep?: Dep = undefined        // 依赖自己的 effects(例如渲染函数)
  private _value!: T                 // 缓存值
  private _dirty = true              // 脏标志:true 表示需要重新计算
  public readonly effect: ReactiveEffect<T>
  constructor(getter: () => T) {
    // 关键:传进去一个自定义调度器
    this.effect = new ReactiveEffect(getter, () => this.trigger())
  }
  get value() {
    // 读 value 时
    if (this._dirty) {
      this._dirty = false
      this._value = this.effect.run()!
    }
    trackRefValue(this)              // 收集当前 computed 的依赖
    return this._value
  }
}

# 32. 什么是虚拟 DOM?

虚拟 DOM(Virtual DOM)是一种编程概念,它是对真实 DOM 的一种抽象,它描述了真实 DOM 的结构及内容,但不包含实际的 DOM 节点,而是用一个 JavaScript 对象来描述 DOM 节点及其属性。

# 33. Vue3 的 diff 算法是怎样的?

Vue3 的 diff 算法是基于 key 和索引位置的,即通过比较新旧 VNode 的 key 和索引位置来判断是否需要更新,如果 key 相同,则认为是相同节点,否则认为是不同的节点。

Vue3 与 Vue2 的 diff 算法核心区别在于对比策略和性能优化逻辑,Vue3 通过双端对比+最长递增子序列(LIS)实现了更高效的 DOM 更新,具体差异可从以下 4 点展开:

  1. 核心对比算法不同
  • Vue2:采用单端(从左到右)diff。 仅从列表头部开始逐一对比节点(依赖  key  匹配),遇到不匹配节点时,直接删除旧节点、新增新节点,中间节点即使顺序变化也会频繁移动,长列表场景下性能开销较高。
  • Vue3:采用双端快速 diff。 同时从新旧列表的头部和尾部双向对比,优先复用首尾相同节点,快速缩小需处理的节点范围,减少无效对比步骤。
  1. 节点移动优化逻辑不同
  • Vue2:无专门的移动优化。 当列表节点顺序调整时,会通过“暴力对比”确定节点位置,移动次数与节点数量呈  O(n²)  关系,节点越多效率越低。
  • Vue3:基于最长递增子序列(LIS)优化。 对剩余待处理节点,通过计算“新节点在旧列表中的索引序列”的 LIS,让 LIS 对应的节点保持不动(已有正确顺序),仅移动非 LIS 节点,将移动复杂度降至  O(n log n) ,长列表性能提升显著。
  1. 对比范围与效率不同
  • Vue2:对比范围固定,需遍历整个列表。 即使列表首尾节点完全一致,也需从头遍历到尾,无法提前缩小处理范围,存在冗余计算。
  • Vue3:对比范围动态缩小。 双向对比过程中,每匹配一个首尾节点就移动一次指针(头部指针后移、尾部指针前移),直到指针交叉,仅处理中间剩余的“差异节点”,对比效率更高。
  1. 边界场景处理不同
  • Vue2:对“新列表有剩余/旧列表有剩余”的场景处理直接,但无优先级。 无论剩余节点在列表头部、尾部还是中间,均按统一逻辑删除/新增,未优先复用已有节点。
  • Vue3:优先处理首尾剩余节点。 双端对比时,若头部或尾部存在剩余节点(如新列表尾部多一个节点),可直接在对应位置新增/删除,无需遍历中间节点,进一步减少操作步骤。

# 34. Vue3 的 diff 算法的优化?

Vue3 的 diff 算法的优化主要有:

  1. 静态节点:将静态节点提升到父节点,减少 diff 计算量。
  2. 异步渲染:将渲染过程分为多个任务,并在浏览器空闲时执行,减少渲染时间。
  3. 事件优化:将事件处理函数缓存到数组,避免重复绑定。
  4. 生命周期优化:将生命周期函数缓存到数组,避免重复调用。
  5. 优化触发器:使用位运算标记触发器,减少触发器的执行。
  6. 优化更新:使用位运算标记更新,减少更新的执行。
  7. 优化依赖收集:使用 WeakMap 代替 Map 进行依赖收集,减少内存占用。
  8. 优化触发器和更新:使用位运算标记触发器和更新,减少触发器和更新的执行。

# 35. Vue 3.0 中 Treeshaking 特性是什么,并举例进行说明?

Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination

  1. 编译阶段利用 ES6 Module 判断哪些模块已经加载
  2. 判断那些模块和变量未被使用或者引用,进而删除对应代码

# 36. 使用 Proxy API 替代 defineProperty API 是为了改进响应式系统的性能和功能:

使用 Proxy API 取代 defineProperty API 是为了提升性能、增强功能,并提供更好的开发体验和错误提示。这些改进使得 Vue 3.0 的响应式系统更加高效、灵活和可靠。

  1. 性能提升
  2. 更全面的拦截能力:Proxy API 提供了更多的拦截方法,比 defineProperty API 更灵活、丰富。它支持拦截目标的各种操作,包括读取、设置、删除、枚举等,甚至还可以拦截函数调用和构造函数实例化。
  3. 更好的数组变化检测:Vue 3.0 使用 Proxy API 改善了数组的变化检测机制。Proxy 可以直接拦截数组的索引访问和修改,使得对数组的变化更容易被监听到,从而提供了更可靠的响应式行为。
  4. 更易于处理嵌套对象:Proxy API 能够递归地拦截对象的嵌套属性,而 defineProperty 无法自动递归处理嵌套对象。这使得在 Vue 3.0 中处理嵌套对象更加简单和方便。
  5. 更好的错误提示:相比于 defineProperty,Proxy API 提供了更好的错误追踪和调试信息。当使用 Proxy API 时,如果访问或修改了一个不存在的属性,会直接抛出错误,从而更容易发现和修复问题。

# 37. Vue3.0 性能提升主要是通过哪几方面体现的?

  1. 优化的渲染机制:Vue3.0 采用异步渲染机制,将渲染过程分为多个任务,并在浏览器空闲时执行,减少渲染时间。
  2. SSR 优化
  3. 源码体积
  4. 响应式系统
  5. 引入 tree-shaking,可以将无用模块“剪辑”,仅
  6. diff 算法优化
  7. 静态提升
  8. 事件监听缓存

# 38. 你是怎么处理 vue 项目中的错误的?

  1. 组件级更细粒度:onErrorCaptured
  2. 异步错误 路由:router.onError(handler) 事件:window.addEventListener('unhandledrejection', handler)
  3. Axios 拦截器
  4. Sentry、PageSpy
  5. app.config.errorHandler
  6. window.addEventListener('unhandledrejection', (e) => {})
  7. window.addEventListener('error', (e) => {})

# 39. 自定义指令是什么?有哪些应用场景?

自定义指令(Custom Directive)是一种用于扩展 Vue 的模板语法的机制。通过自定义指令,你可以在 DOM 元素上添加自定义行为,并在元素插入、更新和移除时进行相应的操作。

应用场景:

  1. 操作 DOM
  2. 表单验证
  3. 自定义组件
  4. 动画
  5. 权限控制
  6. 第三方插件

# 40. 修饰符是什么

修饰符处理了许多 DOM 事件的细节

  1. 表单修饰符
  2. 事件修饰符
  3. 鼠标按键修饰符
  4. 键值修饰符
  5. v-bind 修饰符

# 41. 说说你对 Vue 中 keep-alive 的理解

keep-alive 是 vue 中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染 DOM

  1. include - 字符串或正则表达式。只有名称匹配的组件会被缓存
  2. exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存
  3. max - 最多缓存多少组件实例

# 42. 说说 vue 中,key 的原理

Vue 在进行虚拟 DOM 的 diff 算法时,会使用 key 来匹配新旧节点,以确定节点的更新、移动或删除。它通过 key 属性来判断两个节点是否代表相同的实体,而不仅仅是根据它们的内容是否相同。这样可以保留节点的状态和避免不必要的 DOM 操作。

key 必须是唯一且稳定的,最好使用具有唯一标识的值,例如使用数据的唯一 ID。同时,不推荐使用随机数作为 key,因为在每次更新时都会生成新的 key,导致所有节点都重新渲染,无法复用已有的节点,降低性能。

# 43. slot 是什么

  1. 默认插槽

  2. 具名插槽

    <!-- 子组件 -->
    <template>
      <slot>默认插槽后备的内容</slot>
      <slot name="content">具名插槽后备的内容</slot>
    </template>
    
    <!-- 父组件 -->
    <template v-slot:default>默认插槽内容</template>
    
    <template v-slot:content>具名插槽⽤插槽名做参数...</template>
    
  3. 作用域插槽

# 44. Vue 中的$nextTick 有什么作用?

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

# 45. Vue 组件的通信方式有哪些?

  1. props:父组件向子组件传递数据
  2. $emit:子组件向父组件触发事件
  3. $parent:子组件获取父组件的实例
  4. $children:父组件获取子组件的实例
  5. $refs:获取组件实例
  6. eventBus:发布订阅模式
  7. vuex:全局状态管理
  8. provide/inject:祖先组件向后代组件提供数据或方法
  9. $attrs/$listeners:获取不被插槽内容的属性和事件
  10. 插槽:子组件向父组件传递内容
  11. Vue 3.4 开始,推荐的实现方式是使用 defineModel()
// 3.4之前使用
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
<!-- Child.vue -->
<script setup>
const model = defineModel()

function update() {
  model.value++
}
</script>

<template>
  <div>Parent bound v-model is: {{ model }}</div>
  <button @click="update">Increment</button>
</template>
<!-- Parent.vue -->
<Child v-model="countModel" />

# 46. Vue 中组件和插件有什么区别?

组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在 Vue 中每一个.vue 文件都可以视为一个组件 组件的优势:

  1. 复用性:组件可以被复用,可以提高开发效率
  2. 封装性:组件可以封装一些公共逻辑,使得代码更加整洁
  3. 可测试性:组件可以被测试,提高代码质量

插件就是扩展 Vue 的功能,插件可以包含组件、指令、过滤器等各种功能,插件可以被安装到 Vue 实例上,也可以单独使用。 插件的优势:

  1. 扩展性:插件可以扩展 Vue 的功能,使得 Vue 功能更加强大
  2. 定制化:插件可以定制化开发,满足不同项目的需求
  3. 社区支持:插件的社区支持是其优势之一

# 47. 为什么 Vue 中的 data 属性是一个函数而不是一个对象?

函数作用域隔离组件之间的数据污染

# 48. SPA(单页应用)首屏加载速度慢怎么解决?

  1. 减小入口文件积
  2. 静态资源本地缓存
  3. UI 框架按需加载
  4. 图片资源的压缩、使用字体图标
  5. 路由懒加载
  6. 开启 GZip 压缩
  7. 开启服务端渲染

# 49. Vue 实例挂载的过程中发生了什么?

  1. 创建应用实例(createApp)
  2. 执行 mount 方法,启动挂载流程
  3. 将虚拟 DOM 渲染为真实 DOM(patch 阶段)
  4. 触发生命周期钩子
  5. 建立更新机制
上次更新: