Vue3 响应式语法糖
ref 与 响应式变量($ref)
响应式的变量可以像普通变量那样被访问和重新赋值,但这些操作在编译后都会变为带 .value 的 ref。响应式对象存在解构丢失响应性的问题,而 ref 需要到处使用 .value 则感觉很繁琐.
Vue 响应式语法糖 提供了一个 $ref() 方法是一个编译时的宏命令。它不是一个真实的、在运行时会调用的方法。而是用作 Vue 编译器的标记,表明最终的 变量需要是一个响应式变量。
ref
ref 得通过 ref.value 访问, 有时会我们会忘记使用 .value 而丢失响应性。
$ref
通过 使用宏命令 $ 编译后都会变为带 .value 的 ref 。
每一个会返回 ref 的响应式 API 都有一个相对应的、以 $ 为前缀的宏函数。包括以下这些 API:
ref -> $ref
computed -> $computed
shallowRef -> $shallowRef
customRef -> $customRef
toRef -> $toRef
当启用响应性语法糖时,这些宏函数都是全局可用的、无需手动导入。但如果你想让它更明显,你也可以选择从 vue/macros 中引入它们:
用 $() 将现存的 ref 转换为响应式对象
在某些场景中我们可能已经有了会返回 ref 的函数。然而,Vue 编译器并不能够提前知道该函数会返回一个 ref。那么此时可以使用 $() 宏来将现存的 ref 转换为响应式变量。
Props 响应式
两个痛点
失去响应性
和 ref 一样,都得通过 .value ,为了保持响应性,通过 props.x 来访问 prop ,得到的变量将不是响应式的、也不会更新。
定义默认值笨拙
当使用基于类型的 props 的声明时,无法很方便地声明这些 prop 的默认值。为此我们提供了 withDefaults() 这个 API,但使用起来仍然很笨拙。
解决痛点
当 defineProps 与解构一起使用时,我们可以通过应用编译时转换来解决这些问题,类似于我们之前看到的 $()
函数间传递时的响应性
参数形式传入函数 保持响应式
当 一个函数期望接收一个 ref 对象为参数时,我们可以这样写
$$() 的效果就像是一个转义标识:$$() 中的响应式变量不会追加上 .value。
作为函数返回值
如果将响应式变量直接放在返回值表达式中会丢失掉响应性:
() 调用时任何对响应式变量的引用都会保留为对相应 ref 的引用, 这样保留了响应性。有点像 React Hooks 。
开启响应性语法糖
默认是关闭的状态,需要你显式选择启用。此外,以下列出的所有配置都需要 vue@^3.2.25。
Vite
需要 @vitejs/plugin-vue@>=2.0.0
应用于 SFC 和 js(x)/ts(x) 文件。在执行转换之前,会对文件进行快速的使用检查,因此不使用宏的文件应该不会有性能损失。
注意 reactivityTransform 现在是一个插件的顶层选项,而不再是位于 script.refSugar 之中了,因为它不仅仅只对 SFC 起效。
Vue-CLi
目前仅对 SFC 起效
需要 vue-loader@>=17.0.0
Webpack + Vue-loader
目前仅对 SFC 起效
需要 vue-loader@>=17.0.0
版权声明: 本文为 InfoQ 作者【程序员海军】的原创文章。
原文链接:【http://xie.infoq.cn/article/95d34e0b6e349a83e17dd7331】。文章转载请联系作者。
评论