Skip to content

Vue

vue 父子组件生命周期执行顺序

挂载阶段执行顺序为:
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

更新阶段执行顺序为:
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

销毁阶段执行顺序为:
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

规律就是:父组件先开始执行,然后等到子组件执行完,父组件收尾。

Vue 的 v-for 和 v-if 的优先级

在 vue2 中,v-for 的优先级高于 v-if
在 vue3 中,v-if 的优先级高于 v-for
通常不推荐两种方法一起使用

Vue 组件的通讯方式都有什么

vue2:

props
$emit / v-on
.sync
v-model
ref
$children / $parent
$attrs / $listeners
provide / inject
EventBus
Vuex
$root
slot

vue3:

props
$emit
expose / ref
$attrs
v-model
provide / inject
mitt
Vuex
pinia

vue 修饰符

事件修饰符

Vue.js 中的事件修饰符用于修改事件处理行为。

  • .stop: 阻止事件传播。
  • .prevent: 阻止元素默认行为。
  • .capture: 使用事件捕获模式。
  • .self: 仅在事件目标是当前元素时触发处理函数。
  • .once: 事件仅触发一次。
  • .passive: 告诉浏览器不阻止事件默认行为。

表单修饰符

  • .lazy: 仅在 change 事件后同步数据。
  • .number: 自动将输入值转换为数字。
  • .trim: 自动过滤首尾空白字符。

Vue 的生命周期

  • beforeCreate 组件实例被创建之初,data 和 methods 中的数据还没有初始化
  • created 组件实例已经完全创建,data 和 methods 都已经初始化好了
  • beforeMount 模板渲染,相关的 render 函数首次被调用,模板已经在内存中编译好了,但是尚未挂载到页面中去
  • mounted el 被新创建的 vm.el 替 换 , 真 实 dom 已 经 生 成 , el 替换,真实 dom 已经生成,el 替换,真实 dom 已经生成,el 可用,组件脱离创建阶段,进入运行阶段
  • beforeUpdate 组件数据更新之前调用, 此时页面中显示的数据还是旧的,但 data 是最新的,页面尚未和最新的数据保持同步
  • update 组件数据更新之后,页面和 data 数据已经保持同步,都是最新的
  • beforeDestory 组件销毁前调用,vue 实例从运行阶段进入到销毁阶段,这时 vue 实例身上所有都可用,还没有真正执行销毁
  • destoryed 组件销毁后调用,vue 实例上的所有都不可以用了
  • activited keep-alive 专属,组件被激活时调用
  • deactivated keep-alive 专属,组件被销毁时调用

vue 双向绑定的原理

Vue.js 的双向绑定原理是通过数据劫持和发布-订阅模式实现的。

数据劫持

Vue.js 会劫持数据对象的属性,并在属性发生变化时触发相应的事件。

发布-订阅模式

Vue.js 使用发布-订阅模式来实现组件之间的通信。当数据发生变化时,Vue.js 会发布一个事件,组件可以订阅这个事件并作出相应的反应。

双向绑定的实现

当用户在输入框中输入内容时,Vue.js 会劫持输入框的 value 属性,并在 value 属性发生变化时触发 input 事件。

组件订阅 input 事件,并在 input 事件触发时更新数据对象中的相应属性。

当数据对象中的属性发生变化时,Vue.js 会发布一个事件,组件订阅这个事件并作出相应的反应,例如更新视图。

为什么 data 是一个函数

Vue 中,每次复用组件,需要每个组件中都有自己的 data,这样组件之间才不会相互干扰。

组件中的 data 如果写成对象形式,就多个组件实例会共用了一份 data,一个数据变化后,会影响其他实例中的数据。

data 写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的 data,类似于给每个组件实例创建一个私有的数据空间,不干扰其他组件的运行。

Vue 中 router 和 route 的区别

  • router 是 VueRouter 的一个实例,包含了所有的路由规则和钩子函数等。
  • route 是一个路由信息对象,包含了当前路由的各种信息,例如路径、参数、查询参数等。

MVC 与 MVVM

MVC (Model-View-Controller)MVVM (Model-View-ViewModel) 是两种常见的软件架构模式,主要用于组织和管理代码,使其更易于维护和扩展。

MVC 模式由以下三个部分组成:

  1. Model(模型):负责处理应用程序中的数据逻辑。
  2. View(视图):负责展示数据给用户,也就是用户界面。
  3. Controller(控制器):负责连接模型和视图,处理用户交互,并更新模型和视图。

在 MVC 中,控制器是关键,它处理用户的输入,更新模型,然后再更新视图。这种模式在很多框架中都有应用,如 Ruby on Rails,Spring MVC 等。

MVVM 模式由以下三个部分组成:

  1. Model(模型):同样负责处理应用程序中的数据逻辑。
  2. View(视图):同样负责展示数据给用户,也就是用户界面。
  3. ViewModel(视图模型):它是视图的抽象,负责连接模型和视图。它包含了视图需要的所有状态和行为。

MVVM 的主要特点是数据绑定:ViewModel 中的数据变化会自动更新到视图中,视图中的用户交互也会自动反映到 ViewModel 中。这种模式在很多前端框架中都有应用,如 AngularJS,Vue.js,Knockout.js 等。

总的来说,MVVM 相比于 MVC,更加强调数据驱动的视图,使得视图和模型之间的同步更加自动化,从而减少了很多模板化的代码。但是,它也可能导致更复杂的数据流和更难以理解的代码。

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

组件

组件是 Vue 中的基本构建块,它可以被视为一个独立的、可重用的 Vue 实例,拥有自己的数据、方法和生命周期钩子。每一个 Vue 文件都可以被视为一个组件,它们可以帮助我们构建出复杂的 UI,而且可以重复使用。

组件的优势在于:

  • 降低系统的耦合度:我们可以更换不同的组件来快速满足需求。
  • 方便调试:由于系统是由组件组合起来的,我们可以通过排除法来定位问题。
  • 提高可维护性:由于组件的职责单一,而且在系统中被复用,我们可以通过优化代码来提升系统的性能。

插件

插件是用来为 Vue 添加全局功能的。它们可以添加全局的方法或属性,添加全局资源(如指令、过滤器、过渡等),通过全局混入来添加一些组件选项,或者添加 Vue 实例方法。

插件的编写和注册方式与组件有所不同。插件需要暴露一个install方法,这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。而插件的注册则是通过Vue.use()方法来进行的。

区别

组件和插件的主要区别在于编写形式、注册形式和使用场景。

  • 编写形式:组件通常是.vue 文件,而插件则需要暴露一个install方法。
  • 注册形式:组件可以全局注册或局部注册,而插件则通过Vue.use()方法来注册。
  • 使用场景:组件是用来构成应用的业务模块,而插件则是用来增强 Vue 本身的功能。

简单来说,组件是构成你的应用的业务模块,而插件则是用来增强你的技术栈的功能模块。

slot 插槽

通过插槽可以让用户可以拓展组件,去更好地复用组件和对其做定制化处理,如果父组件在使用到一个复用组件的时候,获取这个组件在不同的地方有少量的更改,如果去重写组件是一件不明智的事情,通过 slot 插槽向组件内部指定位置传递内容,完成这个复用组件在不同场景的应用,比如布局组件、表格列、下拉选、弹框显示内容等。

删除对象用 delete 和 Vue.delete 有什么区别

  • delete:只是被删除对象成员变为' 'undefined,其他元素键值不变
  • Vue.delete:直接删了对象成员,如果对象是响应式的,确保删除能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限制

Vue-Router 钩子函数

首页可以控制导航跳转,beforeEachafterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

  • beforeEach 主要有 3 个参数 tofromnext
  • toroute 即将进入的目标路由对象。
  • fromroute 当前导航正要离开的路由。
  • nextfunction 一定要调用该方法 resolve 这个钩子。执行效果依赖 next 方法的调用参数。可以控制网页的跳转路由跳转

params 和 query 的区别

queryparams 是两种传递路由参数的方式.

  1. 引入方式query 参数通常与 path 一起使用,而 params 参数则与 name 一起使用。例如:

    javascript
    this.$router.push({ path: "user", query: { plan: "private" } });
    this.$router.push({ name: "user", params: { userId: 123 } });
  2. URL 显示query 参数在 URL 中以 ?key=value 的形式显示,类似于 GET 请求的参数。而 params 参数则不会在 URL 中显示,类似于 POST 请求的数据。例如,上述代码中,使用 query 的 URL 会是 /user?plan=private,而使用 params 的 URL 会是 /user

  3. 数据持久性query 参数在页面刷新后仍会保留,在 URL 中直接修改也会反映到应用状态中。而 params 参数在页面刷新后会丢失,且不能直接在 URL 中修改。

  4. 获取方式:获取 queryparams 参数的方式类似,都是通过 this.$route.querythis.$route.params 来获取。例如:

    javascript
    let plan = this.$route.query.plan;
    let userId = this.$route.params.userId;

Vuex 的 5 个核心属性是什么

stategettersmutationsactionsmodules

v-model 原理

v-model 只是语法糖而已

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

TIP

注意: 对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组合文字过程中得到更新。

v-for 为什么要加 key

如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改 / 复用相同类型元素的算法。key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速

更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。

更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

谈一下对 vuex 的个人理解

vuex 是专门为 vue 提供的全局状态管理系统,用于多个组件中数据共享、数据缓存等。(无法持久化、内部核心原理是通过创造一个全局实例 new Vue)

主要包括以下几个模块:

  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
  • Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
  • Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
  • Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
  • Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

Vuex 页面刷新数据丢失怎么解决

需要做 vuex 数据持久化 一般使用本地存储的方案来保存数据 可以自己设计存储方案 也可以使用第三方插件

推荐使用 vuex-persist 插件,它就是为 Vuex 持久化存储而生的一个插件。不需要你手动存取 storage ,而是直接将状态保存至 cookie 或者 localStorage 中

你都做过哪些 Vue 的性能优化

  • 对象层级不要过深,否则性能就会差
  • 不需要响应式的数据不要放到 data 中(可以用 Object.freeze() 冻结数据)
  • v-if 和 v-show 区分使用场景
  • computed 和 watch 区分使用场景
  • v-for 遍历必须加 key,key 最好是 id 值,且避免同时使用 v-if
  • 大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格
  • 防止内部泄漏,组件销毁后把全局变量和事件销毁
  • 图片懒加载
  • 路由懒加载
  • 第三方插件的按需引入
  • 适当采用 keep-alive 缓存组件
  • 防抖、节流运用
  • 服务端渲染 SSR or 预渲染

组件中写 name 选项有哪些好处

  1. 可以通过名字找到对应的组件( 递归组件:组件自身调用自身 )
  2. 可以通过 name 属性实现缓存功能(keep-alive
  3. 可以通过 name 来识别组件(跨级组件通信时非常重要)
  4. 使用 vue-devtools 调试工具里显示的组见名称是由 vue 中组件 name 决定的

什么是 vue 中的虚拟 dom?

虚拟 DOM 是一个 JavaScript 对象,它表示真实 DOM 的结构。它包含了所有 DOM 元素及其属性,以及它们之间的关系。虚拟 DOM 是一个轻量级的表示,它比真实 DOM 更容易创建和更新。

为什么需要虚拟 dom?

虚拟 DOM 有很多优点,包括:

  • 性能: 虚拟 DOM 可以提高应用程序的性能,因为它只需要更新发生变化的元素,而不需要重新渲染整个页面。
  • 可移植性: 虚拟 DOM 可以很容易地移植到不同的平台,因为它与底层的 DOM 实现无关。
  • 可测试性: 虚拟 DOM 很容易测试,因为它是一个 JavaScript 对象,可以很容易地被模拟。

虚拟 dom 是如何转换为真实 dom 的?

虚拟 DOM 是通过一个称为“diffing”的过程转换为真实 DOM 的。diffing 算法会比较虚拟 DOM 和真实 DOM,并找出它们之间的差异。然后,diffing 算法会更新真实 DOM,以使其与虚拟 DOM 一致。

diffing 算法有很多种,但最常用的算法是“双指针算法”。双指针算法从虚拟 DOM 和真实 DOM 的根节点开始,并逐个比较它们的子节点。如果两个子节点是相同的,则它们不会被更新。如果两个子节点是不同的,则真实 DOM 的子节点会被更新为虚拟 DOM 的子节点。

diffing 算法是一个非常高效的算法,它可以快速地更新真实 DOM。这就是为什么虚拟 DOM 可以提高应用程序的性能的原因。

Vue.js 的 Diff 算法

Vue.js 的 Diff 算法是其虚拟 DOM 技术的核心部分。该算法主要用于比较新旧两个虚拟 DOM 树,找出它们之间的差异,并将这些差异有效地应用于实际的 DOM 树上。

Vue.js 的 Diff 算法主要包含以下步骤:

  1. 同级比较:Vue 的 Diff 算法只会在同一层级进行差异比较,不会跨层级比较。这样可以大大提高比较的效率。

  2. 新旧节点的比较:首先,它会比较新旧两个节点。如果两个节点不同,那么这个节点将被完全重新创建,并且也将同时删除旧的节点。

  3. 子节点的比较:如果两个节点相同,那么 Vue 将会递归地比较它们的子节点。

  4. Vnode 的 key 属性:在比较子节点时,Vue 会使用一个基于key的比较策略。如果两个节点的key值相同,Vue 将会认为它们是同一节点,然后递归地比较它们的子节点。如果key不同,那么 Vue 将会删除旧节点,并创建一个新节点。

  5. 列表优化策略:在处理列表时,Vue 使用了一种叫做 LCS(最长递增子序列)的算法,通过这种算法,Vue 可以尽可能地复用已有的元素,减少不必要的元素删除和创建操作。

通过以上的策略,Vue 的 Diff 算法可以有效地找出两个虚拟 DOM 树之间的差异,并高效地更新实际的 DOM。

Vue 单页应用与多页应用的区别

单页应用(SPA)

在 SPA 中,所有的用户交互都在一个页面上发生。页面的不同部分会根据用户的行为和交互进行更新,但不会加载新的页面。 SPA 通过 Ajax 和 Vue.js 的路由库(vue-router)进行页面内容的动态更新。 SPA 通常会在加载时获取所有必要的代码,或者将代码分割成几个包,然后在需要的时候加载相应的包。这意味着在初始加载时可能需要更多的时间,但后续页面的更新会非常快。 SPA 可以提供更流畅的用户体验,因为页面更新不会导致页面的重新加载。

多页应用(MPA)

在 MPA 中,每一个页面都是从服务器获取的一个新的 HTML 文档。这意味着每次用户交互(比如点击一个链接)都会导致页面的重新加载。 MPA 通常使用传统的服务器端渲染(SSR)技术,每次请求都会返回一个完整的新页面。 MPA 在初始页面加载时可能会更快,因为只需要加载当前页面的代码。然而,每次页面更新都需要从服务器获取新的页面,这可能导致延迟。

vue3 中的 ref 和 reactive

  • ref创建的是响应式引用,内部源码也是调用reactive来实现的;

  • ref适用于基础数据类型的响应式处理,而reactive则适用于复杂数据类型的响应式处理;

  • ref在 js 中需要通过.value访问值,而reactive则可以直接访问对象的属性。

vue3 中的 toRef 和 toRefs

  • toRef将一个响应式对象的属性转换为响应式引用;
  • toRefs将一个响应式对象转换为多个响应式引用;
  • toReftoRefs都是通过reactive实现的;
  • toReftoRefs都是浅拷贝,不会追踪对象内部的响应式属性。

vue3 中的 watchEffect

不需要指定监听的数据,会自动监听回调函数中的响应式数据,初始化时会立刻执行

vue3 组件通信

  • props + defineProps
  • defineEmits
  • defineExpose / ref
  • useAttrs
  • v-model(支持多个)
  • provide / inject
  • Vuex / Pinia

Vue3.0 性能提升主要是体现在哪些方面

  1. 响应式系统改进: 在 Vue 3.0 中,响应式系统的核心从 Object.defineProperty 改为了 Proxy 对象。这带来了几个优势:

    • 可以监听动态新增的属性。
    • 可以监听删除的属性。
    • 可以监听数组的索引和 length 属性。
    • 通过 Proxy 的拦截能力,可以更细粒度地控制属性的读取、设置和删除等操作,使得响应式系统更加灵活高效。
  2. 编译阶段优化: Vue 3.0 在编译阶段做了多项优化,以提高渲染性能:

    • 静态节点提升:Vue 3.0 会标记和提升所有的静态节点,diff 的时候只需要对比动态节点内容,从而减少了不必要的比较操作。
    • Fragments(片段)支持:Vue 3.0 允许在模板中不需要唯一根节点,可以直接放置文本或同级标签,提高了模板编写的灵活性。
    • 静态提升:通过 hoistStatic 将所有静态的节点提升到 render 方法之外,只会在应用启动时被创建一次,之后复用,减少了重复创建节点的开销。
    • Patch Flag:在动态标签末尾加上相应的标记,只有带有 patchFlag 的节点才被认为是动态元素,能够快速找到动态节点,而不用逐个逐层遍历,提高了虚拟 DOM diff 的性能。
    • 缓存事件处理函数:引入 cacheHandler 机制,避免每次触发事件都要重新生成全新的函数去更新之前的函数,提高了事件处理的效率。
  3. 源码体积优化: Vue 3.0 相比于 Vue 2.0 整体体积变小,主要通过以下方式实现:

    • Tree Shaking:Vue 3.0 通过静态分析找到没有引入的模块并打上标记,然后将这些未被引用的模块剔除,以减小打包后的代码体积。
    • 只在需要时打包:任何一个函数(如 ref、reactive、computed 等)仅在用到的时候才被打包,通过这种方式避免了不必要的代码被打包进最终的构建文件中,进一步减小了体积。

Vue3 和 Vue2 的主要区别

  1. 性能改进:Vue3 采用了新的编译器和渲染器,以提供更快的性能和更小的体积。新的编译器可以将模板编译成更优化的 JavaScript 代码,新的渲染器则可以更有效地更新 DOM,从而提升性能。

  2. 更小的体积:Vue3 的体积比 Vue2 更小,这使得它更适合用于小型项目或是对性能有严格要求的场景。

  3. 更好的响应性:Vue3 采用了新的响应式系统,可以更有效地跟踪数据的变化,并更新 DOM。这个新的响应式系统使用 Proxy API 重写,可以更好地处理数组和对象的变化。

  4. 更易于使用:Vue3 在易用性方面有所提升,引入了全新的 Composition API,提供更灵活的代码组织和重用方式。此外,Vue3 还允许在同一个组件上使用多个 v-model,这使得处理复杂的表单变得更容易。

  5. 新的内置组件:Vue3 引入了新的内置组件如 Fragment、Teleport 和 Suspense,这些组件可以帮助开发者更好地处理常见的 UI 挑战。

  6. 更好的 TypeScript 支持:Vue3 提供了更好的 TypeScript 支持,源代码完全用 TypeScript 重写,这对于 TypeScript 用户来说,将带来更好的开发体验。

  7. 自定义渲染 API:Vue3 提供了一个更低级别的自定义渲染 API,这使得创建自定义渲染器(如用于原生移动开发的渲染器)变得更容易。

  8. 更多的生命周期钩子:Vue3 提供了几个新的生命周期钩子,比如 onServerPrefetch, onRenderTracked, 和 onRenderTriggered,这为开发者提供了更多的灵活性。

  9. 更好的生态系统:Vue3 拥有更好的生态系统,支持更多组件、库和工具,帮助开发人员构建复杂的应用程序。

  10. Pinia 状态管理:Pinia 是 Vue 3 的新状态管理库,可以作为 Vuex 的替代品。Pinia 提供了一种更简单、更直观的方式来管理状态,而且它完全支持 TypeScript 和 Vue DevTools。Pinia 允许你将状态、操作和获取器组织在一起,使得代码更易于理解和维护。

总的来说,Vue3 是一个比 Vue2 更快、更小、更具响应性和更易于使用的框架,它拥有更好的生态系统,使开发人员可以更轻松地构建更复杂的应用程序。

vue3.0 的生命周期

在 Vue 3.0 中,与 Vue 2.x 中的生命周期钩子对应关系如下:

  1. Vue 2.x 钩子与 Composition API 形式的生命周期钩子对应关系:

    • beforeCreate ===> setup():在 Vue 3.0 中,setup()函数承担了 Vue 2.x 中beforeCreate生命周期钩子的功能,在此阶段可以进行数据观测和初始化事件。
    • created ========> setup():同样地,setup()函数也承担了 Vue 2.x 中created生命周期钩子的功能,用于实例创建完成后的配置。
    • beforeMount ===> onBeforeMount:在 Vue 3.0 中,onBeforeMount代替了 Vue 2.x 中的beforeMount,在挂载开始之前被调用。
    • mounted ========> onMounted:类似地,onMounted取代了 Vue 2.x 中的mounted,在实例挂载到 DOM 之后调用。
    • beforeUpdate ===> onBeforeUpdate:Vue 3.0 中的onBeforeUpdate对应 Vue 2.x 中的beforeUpdate,在数据更新前调用。
    • updated =======> onUpdatedonUpdated在 Vue 3.0 中替代了 Vue 2.x 中的updated,在数据更新后调用。
    • beforeDestroy ==> onBeforeUnmount:Vue 3.0 中的onBeforeUnmount对应 Vue 2.x 中的beforeDestroy,在实例销毁之前调用。
    • destroyed ======> onUnmounted:最后,onUnmounted取代了 Vue 2.x 中的destroyed,在实例销毁后调用。
  2. Vue 实例的完整生命周期解释:

    • beforeCreate(创建前):在实例初始化之后,数据观测和事件配置之前调用。
    • created(创建后):在实例创建完成后调用,此时实例已完成配置,但尚未挂载到 DOM 上。
    • beforeMount(挂载前):在挂载开始之前调用,相关的 render 函数首次被调用。
    • mounted(挂载后):在实例挂载到 DOM 后调用,此时 DOM 已完成渲染。
    • beforeUpdate(更新前):在数据更新时调用,此时虽然数据已更新,但 DOM 尚未重新渲染。
    • updated(更新后):在数据更新后调用,DOM 已经重新渲染。
    • beforeDestroy(销毁前):在实例销毁之前调用,此时实例仍然可用。
    • destroyed(销毁后):在实例销毁之后调用,所有绑定和事件监听器都已解除。

以上是 Vue 实例的完整生命周期,每个阶段都有其特定的作用和时机。在 Vue 3.0 中,虽然有一些生命周期钩子的命名变化,但其功能与 Vue 2.x 中的生命周期钩子是一致的,只是名称有所调整。

Composition Api 与 Options Api 有什么不同

1. 逻辑组织

  • Options API: 逻辑分散在不同的选项(data、computed、methods、watch)中,这使得复杂组件的理解和维护变得困难。
  • Composition API: 逻辑根据功能组织成函数,使代码更具可读性和可维护性。

2. 逻辑复用

  • Options API: 使用 mixin 实现逻辑复用,但会带来命名冲突和数据来源不清晰的问题。
  • Composition API: 使用函数式 API 实现逻辑复用,避免了命名冲突,并提供了清晰的数据来源。

其他区别:

  • 类型推断: Composition API 具有更好的类型推断,因为它主要使用函数。
  • tree-shaking: Composition API 对 tree-shaking 友好,可以更好地压缩代码。
  • this 指向: Composition API 中不使用 this,消除了 this 指向不明的问题。

总结:

Composition API 在逻辑组织和逻辑复用方面优于 Options API,并且具有更好的类型推断、tree-shaking 友好和 this 指向明确的优点。对于小型组件,Options API 仍然是一个不错的选择,但对于复杂组件,Composition API 是一个更强大的选择。

SPA 首屏优化方式

  • 减小入口文件积
  • 静态资源本地缓存
  • UI 框架按需加载
  • 图片资源的压缩
  • 组件重复打包
  • 开启 GZip 压缩
  • 使用 SSR

Vue 3 初始化流程

简化流程:

createApp() => mount() => render() => patch() => processComponent() => mountComponent()

详细流程:

  1. Vue.createApp() 执行 renderer.createApp(),创建渲染器实例。
  2. 渲染器实例的 createApp() 方法调用 createAppAPI(),返回一个接受 render 函数的函数。
  3. createAppAPI() 返回的函数创建 Vue 实例,并定义 mount 方法。
  4. mount 方法调用 render 函数,将虚拟 DOM 转换为真实 DOM。
  5. render 函数调用 patch 函数,将虚拟 DOM 与真实 DOM 进行比较并更新。
  6. patch 函数调用 processComponent 函数,处理组件的挂载和更新。
  7. processComponent 函数调用 mountComponent 函数,挂载或更新组件。