vue3.4.0-alpha.2&alpha.3 的功能更新

注:本文采用vue版本为3.4.0-alpha.3

之前我们提到了vue3.4.0-alpha.1 响应式逻辑的变动。而在今天,vue 发布了vue3.4.0-alpha.2&alpha.3版本,alpha.3版本算是对alpha.2的补充,因此合起来讲。

其实vue3.4.0-alpha.2 的一些功能在之前就已经处于待合并状态,但直到这次发布之前尚未被合并。现在我们有机会深入了解这些功能。

Reactivity Transform 被废弃

Reactivity Transform 可以翻译为响应式语法糖。这个功能在3.3版本被标记为不推荐使用。而在当前版本中,这个功能已经被彻底移除了。

如果有开发者仍希望使用这个功能,可以通过vue-macros来继续使用。

这个功能官网有详细说明,并且被彻底废弃,因此这里不再探讨详细用法以及实现原理,概括来说,可以通过一系列宏命令,实现去掉ref.value以及将ref转化为响应式对象等功能。

本身Reactivity Transform是为了提供更简洁的语法来改善开发体验,但却发现了不少问题。可以看这个讨论,概括如下:

  1. 失去了 .value 导致难以确定哪些内容正在被追踪以及哪些代码触发了响应式效果。这增加了在大型代码库中使用时的心智负担。 一些用户选择只在单文件组件内使用 Reactivity Transform,导致了不一致性和不同心智模型之间的切换成本。
  2. 由于外部函数仍需原始引用(raw refs),在 Reactive Variables 和原始引用之间的转换增加了学习和心智负担,尤其对初学者不友好。
  3. 存在潜在的碎片化风险,因为一些用户反对这个功能,担心在不同的代码库中工作时可能会遇到使用和不使用该功能的情况,扰乱了 JavaScript 的语义。

因此在这个版本被正式移除。

暴露computed上一个计算结果

这个功能还是响应式逻辑变动的那位老哥进行贡献的。

typescript 复制代码
import isEqual from 'lodash.isequal';

const a = ref(1);
const b = ref(2);
const c = computed(oldValue => {
	const newValue = { a: a.value, b: b.value };
	return isEqual(oldValue, newValue) ? oldValue : newValue;
});

现在计算属性存在入参了,入参的值为上次计算结果。

正常来说,我们在使用Vue的过程中,无法通过计算属性本身来获取它上次的计算结果,但实际上,计算属性一直缓存着上一次计算结果_value

经过alpha.1响应式逻辑变动,如果标记为脏状态,那么就会使用effect.run()获取最新计算结果,赋值给_value,而构建计算属性的effect的时候,会将_value传入getter形成新的getter函数() => getter(this._value),这样会导致,执行effect.run()的时候,会自动携带_value,从而实现,在计算属性的入参,获取上次计算结果。

改进语言工具对代码解析的容错性

在之前的情况下,也就是标准的HTML解析中,下面的代码

js 复制代码
<template><Hello\n</template><script>console.log(1)</script>

会被解析成

html 复制代码
<template>
    <hello\n< template="">
        <script>console.log(1)</script>
    </hello\n<>
</template>

会忽略斜杠,将<template视为Hello开放标签的属性,导致<template>无法关闭,而<script>被解析为其子元素。

这显然与预期不符。

因此增加了一段特殊处理逻辑

typescript 复制代码
  private peek() {
    return this.buffer.charCodeAt(this.index + 1)
  }
  
 // 略
 if (c === CharCodes.Lt && this.peek() === CharCodes.Slash) {
      this.cbs.onopentagend(this.index)
      this.state = State.BeforeTagName
      this.sectionStart = this.index
    } 

如果处于处理开放标签状态时,同时遇到<字符,并且接下来的字符是/,那么就视为结束标签。

支持 v-bind 的简写语法

我们可以使用v-bind在标签上绑定属性,并且可以省略v-bind,使用缩写绑定。

html 复制代码
<input v-bind:value="value" />
<input :value="value" />

现在,如果绑定是属性与数据同名,那么我们可以进一步省略。

html 复制代码
     <input v-bind:value />
<!-- <input v-bind:value="value" /> -->
     <input :value />
<!-- <input :value="value" /> -->
     <input .value />
<!-- <input .value="value" /> -->
     <input :value.attr />
<!-- <input :value.attr="value" /> -->
     <input :value-key.camel />
<!-- <input :value-key.camel="valueKey" /> -->

对应的改动代码也较为简洁

typescript 复制代码
// 单独从dir解构exp
let { exp } = dir
// 如果exp不存在,并且是SIMPLE_EXPRESSION
if (!exp && arg.type === NodeTypes.SIMPLE_EXPRESSION) {
  // 提取属性名
  const propName = camelize(arg.content)
  // 根据属性名计算出exp,也就是:arg替换成:arg="arg"
  exp = dir.exp = createSimpleExpression(propName, false, arg.loc)
}

将生产构建中的错误链接到文档

我们在vue3.4.0-alpha.1 其他变动提到了导出错误代码,现在,Vue在生产环境中,如果发生错误,那么不仅仅抛出对应的错误码或者错误类型,还会附带对应的网址,可以查阅错误详细信息。

typescript 复制代码
// errors.ts
 const msg =
    __DEV__ || !__BROWSER__
      ? (messages || errorMessages)[code] + (additionalMessage || ``)
      : code
      : `https://vuejs.org/errors/#compiler-${code}`
// errorHandling.ts
const errorInfo = __DEV__
      ? ErrorTypeStrings[type]
      : `https://vuejs.org/errors/#runtime-${type}`
相关推荐
m0_748236112 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo61714 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_7482489416 分钟前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_7482356127 分钟前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink5 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者7 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-7 小时前
验证码机制
前端·后端
燃先生._.8 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js