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}`
相关推荐
2501_9209317017 分钟前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05281 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔1 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李1 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN1 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒1 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库1 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
方也_arkling1 小时前
Element Plus主题色定制
javascript·sass
电商API_180079052471 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫
晓晓莺歌1 小时前
vue3某一个路由切换,导致所有路由页面均变成空白页
前端·vue.js