从争议到巅峰:Vue3 的奇迹之旅 —— 从‘海贼王’到‘灌篮高手’的变革历程

前端训练营:1v1私教,终身辅导计划,帮你拿到满意的 offer 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~

Hello,大家好,我是 Sunday。

Vue 官方团队在 2023 年的最后两天发布了 Vue 3.4 的版本命名为 “Slam Dunk”(灌篮高手)。Vue3 自 2020 年发布,到目前为止已经有 三年半 的时间(想不到吧,Vue3 已经发布了这么久了)。期间经历了很多关键节点的变化,从最初的 被人诟病 到现在的 “全面认可” 中间到底经历了什么?

那么在 23 年末的今天,就让咱们回顾一下整个 Vue3 的生命历程,看看从 海贼王灌篮高手 的变化吧~~

2020年9月18日:Vue 3.0 海贼王 – 发布

从争议到巅峰:Vue3 的奇迹之旅 —— 从‘海贼王’到‘灌篮高手’的变革历程_第1张图片

Vue 3 于 2020年9月18日 正式发布,命名 海贼王。 Vue 官方团队雄心壮志,宣布了很多全新的特性,比如:Composition API但是: 简陋的 setup 函数特性让很多开发者对 Composition API 的易用性产生了 “怀疑”。所以 海贼王 在一开始的推广中 并不顺利~

今天我们很自豪地宣布 Vue.js 3.0“海贼王”正式发布。该框架的这个新的主要版本提供了改进的性能、更小的包大小、更好的 TypeScript 集成、用于处理大规模用例的新 API,并为该框架的长期未来迭代奠定了坚实的基础。

3.0 版本代表了超过 2 年的开发工作,包括 30 多个 RFC、2,600 多个提交、来自 99 个贡献者的 628 个拉取请求,以及核心存储库之外的大量开发和文档工作。我们要对接受这一挑战的团队成员、拉取请求的贡献者、提供财务支持的赞助商和支持者以及参与我们的设计讨论并为预发布提供反馈的更广泛的社区表示最深切的感谢。 -发布版本。 Vue 是一个为社区创建并由社区维持的独立项目,如果没有您的持续支持,Vue 3.0 就不可能实现。

进一步深化“渐进框架”概念

Vue 从一开始就有一个简单的使命:成为一个任何人都可以快速学习的平易近人的框架。随着我们的用户群的增长,该框架的范围也随之扩大,以适应不断增长的需求。随着时间的推移,它演变成我们所说的“渐进式框架”:一个可以逐步学习和采用的框架,同时在用户处理越来越多的要求较高的场景时提供持续的支持。

如今,Vue 在全球拥有超过 130 万用户*,我们看到 Vue 被用于各种各样的场景,从传统服务器渲染页面上的少量交互,到具有数百个组件的成熟单页面应用程序。 Vue 3 进一步增强了这种灵活性。

分层内部模块​

Vue 3.0 核心仍然可以通过简单的

在 SFC Playground 中尝试一下,或者阅读它们各自的文档:

  • 请注意,复杂类型支持是基于 AST 的,因此不是 100% 全面的。一些需要实际类型分析的复杂类型,例如不支持条件类型。您可以对单个 props 的类型使用条件类型,但不能对整个 props 对象使用条件类型。

    通用组件​

    使用

    generic 的值与 TypeScript 中 <...> 之间的参数列表完全相同。例如,您可以使用多个参数、扩展约束、默认类型和引用导入类型:

    
    

    此功能以前需要显式选择加入,但现在在最新版本的 volar / vue-tsc 中默认启用。

    更符合人体工程学的 defineEmits ​

    以前,defineEmits 的类型参数仅支持调用签名语法:

    // BEFORE
    const emit = defineEmits<{
      (e: 'foo', id: number): void
      (e: 'bar', name: string, ...rest: any[]): void
    }>()
    

    该类型与emit的返回类型相匹配,但有点冗长并且写起来很困难。 3.3 引入了一种更符合直觉的用类型声明emits的方式:

    // AFTER
    const emit = defineEmits<{
      foo: [id: number]
      bar: [name: string, ...rest: any[]]
    }>()
    

    在类型文字中,键是事件名称,值是指定附加参数的数组类型。尽管不是必需的,但您可以使用带标签的元组元素来实现明确性,如上面的示例所示。

    仍然支持调用签名语法。

    带有defineSlots的类型插槽​

    新的 defineSlots 可用于声明预期的插槽及其各自的预期插槽 prop:

    
    

    DefineSlots() 仅接受类型参数,不接受运行时参数。类型参数应该是类型文字,其中属性键是槽名称,值是槽函数。函数的第一个参数是插槽期望接收的道具,其类型将用于模板中的插槽道具。 DefineSlots 的返回值与 useSlots 返回的插槽对象相同。

    当前的一些限制:

    • volar / vue-tsc 中尚未实现所需的插槽检查。
    • 槽函数返回类型目前被忽略,可以是任何类型(any),但我们将来可能会利用它来检查槽内容。

    对于defineComponent的使用还有相应的slots选项。这两个 API 都没有运行时影响,纯粹用作 IDE 和 vue-tsc 的类型提示。

    实验特性

    反应式道具解构​

    反应性道具解构以前是反应性变换的一部分,现在已被放弃,现已被分成一个单独的功能。

    该功能允许解构的 props 保留反应性,并提供更符合人体工程学的方式来声明 props 默认值:

    
    
    
    

    此功能是实验性的,需要明确的选择支持。

    defineModel

    以前,对于支持与 v-model 双向绑定的组件,它需要

    • (1) 声明一个 prop 并
    • (2) 在打算更新 prop 时发出相应的 update:propName 事件
    
    
    
    
    

    3.3 通过新的defineModel宏简化了使用。该宏自动注册一个 prop,并返回一个可以直接变异的 ref:

    
    
    
    
    

    此功能是实验性的,需要明确的选择支持。

    其他需要注意的地方

    defineOptions

    新的defineOptions宏允许直接在

    toRef 和 toValue 提供更好的 Getter 支持

    toRef 已得到增强,支持将值/获取器/现有引用规范化为引用:

    // equivalent to ref(1)
    toRef(1)
    // creates a readonly ref that calls the getter on .value access
    toRef(() => props.foo)
    // returns existing refs as-is
    toRef(existingRef)
    

    使用 getter 调用 toRef 类似于计算,但当 getter 仅执行属性访问而不进行昂贵的计算时,效率会更高。

    新的 toValue 实用方法提供了相反的功能,将值/获取器/引用规范化为值:

    toValue(1) //       --> 1
    toValue(ref(1)) //  --> 1
    toValue(() => 1) // --> 1
    

    toValue 可以在可组合项中代替 unref,以便您的可组合项可以接受 getter 作为响应式数据源:

    // before: allocating unnecessary intermediate refs
    useFeature(computed(() => props.foo))
    useFeature(toRef(props, 'foo'))
    
    // after: more efficient and succinct
    useFeature(() => props.foo)
    

    toRef 和 toValue 之间的关系类似于 ref 和 unref 之间的关系,主要区别在于 getter 函数的特殊处理。

    JSX 导入源支持​

    目前,Vue 的类型自动注册全局 JSX 类型。这可能会导致与其他需要 JSX 类型推断的库一起使用的冲突,特别是 React。

    从 3.3 开始,Vue 支持通过 TypeScript 的 jsxImportSource 选项指定 JSX 命名空间。这允许用户根据他们的用例选择全局或每个文件选择加入。

    为了向后兼容,3.3 仍然全局注册 JSX 命名空间。我们计划在 3.4 中删除默认的全局注册。如果您将 TSX 与 Vue 结合使用,则应在升级到 3.3 后将显式 jsxImportSource 添加到 tsconfig.json 中,以避免在 3.4 中出现损坏。

    维护基础设施的改进

    此版本建立在许多维护基础设施改进的基础上,使我们能够更有信心地更快地行动:

    • 通过将类型检查与汇总构建分开并从 rollup-plugin-typescript2 迁移到 rollup-plugin-esbuild,构建速度提高了 10 倍。
    • 从 Jest 迁移到 Vitest,测试速度更快。
    • @microsoft/api-extractor 迁移到 rollup-plugin-dts,更快地生成类型。
    • 通过生态系统-ci 进行全面回归测试 - 在发布之前捕获主要生态系统依赖项的回归!

    按照计划,我们的目标是在 2023 年开始发布更小、更频繁的功能版本。敬请期待!

    2023年12月28日:Vue 3.4 ♪灌篮高手♪ – 发布

    Vue 3.4 的版本对性能进行了很大的提升,比如:模板解析器速度提高了 2 倍,重构了响应系统、defineModel 绑定 props 性能进行了提升

    潜在问题的处理

    • 为了充分利用 3.4 中的新功能,建议在升级到 3.4 时还更新以下依赖项:
      • Volar / vue-tsc@^1.8.27(必填)
      • @vitejs/plugin-vue@^5.0.0(如果使用 Vite)
      • nuxt@^3.9.0(如果使用 Nuxt)
      • vue-loader@^17.4.0(如果使用 webpack 或 vue-cli)
    • 如果将 TSX 与 Vue 结合使用,请检查已删除:全局 JSX 命名空间中所需的操作。
    • 确保您不再使用任何已弃用的功能(如果是,控制台中应该会出现警告)。它们可能已在 3.4 中被删除。

    特色亮点

    2倍更快的解析器和改进的SFC构建性能

    在3.4中,我们完全重写了模板解析器。以前,Vue 使用递归下降解析器,该解析器依赖于许多正则表达式和前瞻搜索。新的解析器使用基于 htmlparser2 中的 tokenizer 的状态机 tokenizer,它仅迭代整个模板字符串一次。结果是解析器对于所有大小的模板来说始终是两倍的速度。得益于我们广泛的测试用例和生态系统-ci,它也 100% 向后兼容 Vue 最终用户。

    在将新的解析器与系统的其他部分集成时,我们还发现了一些进一步提高整体 SFC 编译性能的机会。基准测试显示,在生成源映射的同时编译 Vue SFC 的脚本和模板部分时,性能提高了约 44%,因此 3.4 应该会加快大多数使用 Vue SFC 的项目的构建速度。但是,请注意,Vue SFC 编译只是现实项目中整个构建过程的一部分。与单独的基准测试相比,端到端构建时间的最终收益可能要小得多。

    在 Vue 核心之外,新的解析器还将有利于 Volar / vue-tsc 以及需要解析 Vue SFC 或模板的社区插件的性能,例如Vue 宏。

    更高效的反应系统

    3.4 还对反应性系统进行了重大重构,目标是提高计算属性的重新计算效率。

    为了说明正在改进的内容,让我们考虑以下场景:

    const count = ref(0)
    const isEven = computed(() => count.value % 2 === 0)
    
    watchEffect(() => console.log(isEven.value)) // logs true
    
    count.value = 2 // logs true again
    

    在 3.4 之前,每次 count.value 更改时,watchEffect 的回调都会触发,即使计算结果保持不变。通过 3.4 后的优化,现在仅当计算结果实际发生更改时才会触发回调。

    另外,在3.4中:

    • 多个计算的 dep 更改仅触发同步效果一次。
    • 数组的 shift, unshift, splice 仅触发一次同步效果。

    除了基准测试中显示的收益之外,这还可以减少许多场景中不必要的组件重新渲染,同时保留完全的向后兼容性。

    defineModel 更加稳定

    DefineModel 是一个新的

你可能感兴趣的:(前端训练营,前端,vue)