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}`
相关推荐
小小竹子4 分钟前
前端vue-实现富文本组件
前端·vue.js·富文本
万物得其道者成12 分钟前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
小白小白从不日白13 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风25 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
青稞儿31 分钟前
面试题高频之token无感刷新(vue3+node.js)
vue.js·node.js
diygwcom37 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
volodyan40 分钟前
electron react离线使用monaco-editor
javascript·react.js·electron
^^为欢几何^^1 小时前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
Hello-Mr.Wang1 小时前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js