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 模式由以下三个部分组成:
- Model(模型):负责处理应用程序中的数据逻辑。
- View(视图):负责展示数据给用户,也就是用户界面。
- Controller(控制器):负责连接模型和视图,处理用户交互,并更新模型和视图。
在 MVC 中,控制器是关键,它处理用户的输入,更新模型,然后再更新视图。这种模式在很多框架中都有应用,如 Ruby on Rails,Spring MVC 等。
MVVM 模式由以下三个部分组成:
- Model(模型):同样负责处理应用程序中的数据逻辑。
- View(视图):同样负责展示数据给用户,也就是用户界面。
- 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 钩子函数
首页可以控制导航跳转,
beforeEach
,afterEach
等,一般用于页面title
的修改。一些需要登录才能调整页面的重定向功能。
beforeEach
主要有 3 个参数to
,from
,next
。to
:route
即将进入的目标路由对象。from
:route
当前导航正要离开的路由。next
:function
一定要调用该方法resolve
这个钩子。执行效果依赖next
方法的调用参数。可以控制网页的跳转路由跳转
params 和 query 的区别
query
和 params
是两种传递路由参数的方式.
引入方式:
query
参数通常与path
一起使用,而params
参数则与name
一起使用。例如:javascriptthis.$router.push({ path: "user", query: { plan: "private" } }); this.$router.push({ name: "user", params: { userId: 123 } });
URL 显示:
query
参数在 URL 中以?key=value
的形式显示,类似于 GET 请求的参数。而params
参数则不会在 URL 中显示,类似于 POST 请求的数据。例如,上述代码中,使用query
的 URL 会是/user?plan=private
,而使用params
的 URL 会是/user
。数据持久性:
query
参数在页面刷新后仍会保留,在 URL 中直接修改也会反映到应用状态中。而params
参数在页面刷新后会丢失,且不能直接在 URL 中修改。获取方式:获取
query
和params
参数的方式类似,都是通过this.$route.query
和this.$route.params
来获取。例如:javascriptlet plan = this.$route.query.plan; let userId = this.$route.params.userId;
Vuex 的 5 个核心属性是什么
state
、getters
、mutations
、actions
、modules
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
选项有哪些好处
- 可以通过名字找到对应的组件( 递归组件:组件自身调用自身 )
- 可以通过
name
属性实现缓存功能(keep-alive
)- 可以通过
name
来识别组件(跨级组件通信时非常重要)- 使用
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 算法主要包含以下步骤:
同级比较:Vue 的 Diff 算法只会在同一层级进行差异比较,不会跨层级比较。这样可以大大提高比较的效率。
新旧节点的比较:首先,它会比较新旧两个节点。如果两个节点不同,那么这个节点将被完全重新创建,并且也将同时删除旧的节点。
子节点的比较:如果两个节点相同,那么 Vue 将会递归地比较它们的子节点。
Vnode 的 key 属性:在比较子节点时,Vue 会使用一个基于
key
的比较策略。如果两个节点的key
值相同,Vue 将会认为它们是同一节点,然后递归地比较它们的子节点。如果key
不同,那么 Vue 将会删除旧节点,并创建一个新节点。列表优化策略:在处理列表时,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
将一个响应式对象转换为多个响应式引用;toRef
和toRefs
都是通过reactive
实现的;toRef
和toRefs
都是浅拷贝,不会追踪对象内部的响应式属性。
vue3 中的 watchEffect
不需要指定监听的数据,会自动监听回调函数中的响应式数据,初始化时会立刻执行
vue3 组件通信
- props + defineProps
- defineEmits
- defineExpose / ref
- useAttrs
- v-model(支持多个)
- provide / inject
- Vuex / Pinia
Vue3.0 性能提升主要是体现在哪些方面
响应式系统改进: 在 Vue 3.0 中,响应式系统的核心从 Object.defineProperty 改为了 Proxy 对象。这带来了几个优势:
- 可以监听动态新增的属性。
- 可以监听删除的属性。
- 可以监听数组的索引和 length 属性。
- 通过 Proxy 的拦截能力,可以更细粒度地控制属性的读取、设置和删除等操作,使得响应式系统更加灵活高效。
编译阶段优化: Vue 3.0 在编译阶段做了多项优化,以提高渲染性能:
- 静态节点提升:Vue 3.0 会标记和提升所有的静态节点,diff 的时候只需要对比动态节点内容,从而减少了不必要的比较操作。
- Fragments(片段)支持:Vue 3.0 允许在模板中不需要唯一根节点,可以直接放置文本或同级标签,提高了模板编写的灵活性。
- 静态提升:通过 hoistStatic 将所有静态的节点提升到 render 方法之外,只会在应用启动时被创建一次,之后复用,减少了重复创建节点的开销。
- Patch Flag:在动态标签末尾加上相应的标记,只有带有 patchFlag 的节点才被认为是动态元素,能够快速找到动态节点,而不用逐个逐层遍历,提高了虚拟 DOM diff 的性能。
- 缓存事件处理函数:引入 cacheHandler 机制,避免每次触发事件都要重新生成全新的函数去更新之前的函数,提高了事件处理的效率。
源码体积优化: Vue 3.0 相比于 Vue 2.0 整体体积变小,主要通过以下方式实现:
- Tree Shaking:Vue 3.0 通过静态分析找到没有引入的模块并打上标记,然后将这些未被引用的模块剔除,以减小打包后的代码体积。
- 只在需要时打包:任何一个函数(如 ref、reactive、computed 等)仅在用到的时候才被打包,通过这种方式避免了不必要的代码被打包进最终的构建文件中,进一步减小了体积。
Vue3 和 Vue2 的主要区别
性能改进:Vue3 采用了新的编译器和渲染器,以提供更快的性能和更小的体积。新的编译器可以将模板编译成更优化的 JavaScript 代码,新的渲染器则可以更有效地更新 DOM,从而提升性能。
更小的体积:Vue3 的体积比 Vue2 更小,这使得它更适合用于小型项目或是对性能有严格要求的场景。
更好的响应性:Vue3 采用了新的响应式系统,可以更有效地跟踪数据的变化,并更新 DOM。这个新的响应式系统使用 Proxy API 重写,可以更好地处理数组和对象的变化。
更易于使用:Vue3 在易用性方面有所提升,引入了全新的 Composition API,提供更灵活的代码组织和重用方式。此外,Vue3 还允许在同一个组件上使用多个 v-model,这使得处理复杂的表单变得更容易。
新的内置组件:Vue3 引入了新的内置组件如 Fragment、Teleport 和 Suspense,这些组件可以帮助开发者更好地处理常见的 UI 挑战。
更好的 TypeScript 支持:Vue3 提供了更好的 TypeScript 支持,源代码完全用 TypeScript 重写,这对于 TypeScript 用户来说,将带来更好的开发体验。
自定义渲染 API:Vue3 提供了一个更低级别的自定义渲染 API,这使得创建自定义渲染器(如用于原生移动开发的渲染器)变得更容易。
更多的生命周期钩子:Vue3 提供了几个新的生命周期钩子,比如
onServerPrefetch
,onRenderTracked
, 和onRenderTriggered
,这为开发者提供了更多的灵活性。更好的生态系统:Vue3 拥有更好的生态系统,支持更多组件、库和工具,帮助开发人员构建复杂的应用程序。
Pinia 状态管理:Pinia 是 Vue 3 的新状态管理库,可以作为 Vuex 的替代品。Pinia 提供了一种更简单、更直观的方式来管理状态,而且它完全支持 TypeScript 和 Vue DevTools。Pinia 允许你将状态、操作和获取器组织在一起,使得代码更易于理解和维护。
总的来说,Vue3 是一个比 Vue2 更快、更小、更具响应性和更易于使用的框架,它拥有更好的生态系统,使开发人员可以更轻松地构建更复杂的应用程序。
vue3.0 的生命周期
在 Vue 3.0 中,与 Vue 2.x 中的生命周期钩子对应关系如下:
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
=======>onUpdated
:onUpdated
在 Vue 3.0 中替代了 Vue 2.x 中的updated
,在数据更新后调用。beforeDestroy
==>onBeforeUnmount
:Vue 3.0 中的onBeforeUnmount
对应 Vue 2.x 中的beforeDestroy
,在实例销毁之前调用。destroyed
======>onUnmounted
:最后,onUnmounted
取代了 Vue 2.x 中的destroyed
,在实例销毁后调用。
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()
详细流程:
Vue.createApp()
执行renderer.createApp()
,创建渲染器实例。- 渲染器实例的
createApp()
方法调用createAppAPI()
,返回一个接受render
函数的函数。 createAppAPI()
返回的函数创建 Vue 实例,并定义mount
方法。mount
方法调用render
函数,将虚拟 DOM 转换为真实 DOM。render
函数调用patch
函数,将虚拟 DOM 与真实 DOM 进行比较并更新。patch
函数调用processComponent
函数,处理组件的挂载和更新。processComponent
函数调用mountComponent
函数,挂载或更新组件。