自从引入组合式 API 的概念以来,一个主要的未解决的问题就是 ref 和响应式对象到底用哪个。
响应式对象存在解构丢失响应性的问题,而 ref 需要到处使用 .value 则感觉很繁琐,并且在没有类型系统的帮助时很容易漏掉 .value

2e8b084ed6e50cb5502a5d78669d8950.png

2e8b084ed6e50cb5502a5d78669d8950.png

写法优化

以上是官方原话。大概就是新的语法糖 可以让我们更方便的使用ref,而不用每次都写.value
大概就是把这样的代码,简化成这样

 1<script setup lang="ts">
 2import { ref } from 'vue'
 3
 4const count = ref(0)
 5console.log(count.value)
 6const increment = ()=> {
 7  count.value++
 8}
 9</script>
10
11<template>
12  <button @click="increment">{{ count }}</button>
13</template> 

简化成

 1<script setup lang="ts">
 2const count = $ref(0)
 3console.log(count.value)
 4const increment = ()=> {
 5  count++
 6}
 7</script>
 8
 9<template>
10  <button @click="increment">{{ count }}</button>
11</template> 

每一个会返回 ref 的响应式 API 都有一个相对应的、以 $ 为前缀的宏函数。

 11. ref -> $ref
 22. computed -> $computed
 33. shallowRef -> $shallowRef
 44. customRef -> $customRef
 55. toRef -> $toRef

怎么开启此功能

在vite中启用语法糖开关
打开vite.config.ts,添加如下代码

 1vue({reactivityTransform: true})  

配置tsconfig.json(可选)
在compilerOptions下添加vue/ref-macros
不然会报错`TS2304: Cannot find name ‘$ref’
虽然不影响使用,但是会影响开发体验

 1"compilerOptions":{
 2  "types": ["vue/ref-macros"] 
 3} 

配置eslint(可选)
在eslintrc.cjs中加上global
不然会提示ESLint: '$ref' is not defined.(no-undef)

 1module.exports = {
 2  globals: {
 3    $ref: "readonly",
 4    $computed: "readonly",
 5    $shallowRef: "readonly",
 6    $customRef: "readonly",
 7    $toRef: "readonly"
 8  }
 9}; 

免配上边两个可选
如果不嫌麻烦,又不想代码中总是有误报错误的行为。
可以直接在vue代码中引入vue/ref-macros
这样就不用配置tsconfig.json和eslint了

 1<script setup lang="ts">
 2import { $ref } from "vue/macros";
 3
 4const count = $ref(0)
 5console.log(count.value)
 6const increment = ()=> {
 7  count++
 8}
 9</script>
10
11<template>
12  <button @click="increment">{{ count }}</button>
13</template> 

 

 

个人笔记记录 2021 ~ 2025