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}`
相关推荐
EasyNTS10 分钟前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
活宝小娜2 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点2 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow2 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o2 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic3 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā3 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年4 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder4 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727574 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架