> ## Content Index
> Fetch the complete content index at: https://iiong.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Vue3 第二次提案 ref 语法糖体验
- URL: https://iiong.com/vue3-second-submission-of-ref-syntactic-sugar-experience/
- Published: 2021-08-18T13:52:47.000Z
- Updated: 2026-06-22T15:31:59.000Z
- Description: 在 GitHub Vue Rfcs 369 提案看到又出新的 ref 语法糖提案，说起来在过年写个 vue3 的简易版本的后台系统，之前的 ref 声明确实一点儿不优雅。所以大概看了下社区提案内容，确实可以值得学习。
- Author: 淮城一只猫
- Tags: 编程技术, Vue.js

### 前言

这段时间无论是个人项目还是公司项目主要还是用在 `vue2` 版本上，前几天才整合一个新的后台框架，所以寻思想在 `vue3` 整一个，正好在 [GitHub Vue Rfcs 369](https://github.com/vuejs/rfcs/discussions/369?ref=iiong.com) 提案看到又出新的 `ref` 语法糖提案，说起来在过年写个 `vue3` 的简易版本的后台系统，之前的 `ref` 声明确实一点儿不优雅。所以大概看了下社区提案内容，确实可以值得学习。

### 展示

如果在原始版本写法如下：

```javascript
<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(1)

    console.log(count.value)

    function inc() {
      count.value++
    }

    return () => {
      return h('button', { onClick: inc }, count.value)
    }
  }
}  
</script>

```

是的，各种 `.value` 就很不讨人喜，之前维护 `vue3` 的后台系统，直接给我整吐了。如果摆在新的提案是这样写的：

```html
<template>
  <button @click="inc">{{ count }}</button>
</template>
<script setup>
  // 声明一个编译为 ref 的变量
  let count = $ref(1)

  console.log(count) // 1

  function inc() {
    // 变量可以像普通值一样使用
    count++
  }
</script>

```

这么看确实舒服了点，也更加优雅点，最终经过 `vue-loader` 编译器转化普通的 `javascript` 对象。

### 使用

如果想体验最新的语法需要设置编译器调整，在 `vue.config.js` 配置如下，并且注意 `vue` 版本是 `3.2.0-beta.1` 以上。

```javascript
// vue-cli vue.config.js
module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap((options) => {
        return {
          ...options,
          refSugar: true
        }
      })
  }
}

// vite.config.js
export default {
  plugins: [
    vue({
      script: {
        refSugar: true
      }
    })
  ]
}

// webpack + vue-loader => webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          refSugar: true
        }
      }
    ]
  }
}

```

目前新提案只有四个新东西：`$ref`, `$computed`, `$fromRefs` 和 `$raw`。

#### $ref

正如上面展示，声明一个变量，使它响应式。

#### $computed

等价以前的 `computed` 方法，没什么区别。

#### $fromRefs

用于解构自定义 `refs` 对象：

```javascript
const { x, y, method } = $fromRefs(useFoo())

console.log(x, y)
method()

```

#### $raw

原始 `ref` 对象，等价于 `ref` 声明的值，需要加 `.value` 才能访问响应值：

```javascript
let count = $ref(0)

const countRef = $raw(count)

console.log(countRef.value)

```

#### 嵌套函数作用域中的 Ref 用法

`$ref` 可以用于所有任何一个地方的声明的 `let` 变量，当然常量是毫无意义的：

```javascript
function useMouse() {
  let x = $ref(0)
  let y = $ref(0)

  function update(e) {
    x = e.pageX
    y = e.pageY
  }

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  return $raw({
    x,
    y
  })
}

```

### 结言

不看这个提案我相信下面有很多人在喷尤雨溪，毕竟前面也有几次提案，全部被社区驳回，主要新增的语法糖增加使用者心智负担，说起来这个我感觉还是个人原因比较大，我之前有个同事，和他做个项目我都惊呆了，我不知道他是怎么学习的，据他描述是上手就是 `vue` 一把梭，然后脱离 `vue` 项目就不会搞起来了，指的是让他新建个 `html` 引入 `jquery` 编写小型项目都做不到。虽然 `vue` 很适合快速开发迭代项目，但不深入 `javascript` 未来的路是走不远的，语法糖虽好，但不能贪吃，当使用一个语法糖还是尽量理解它最终形成的样子。