Vue3 第二次提案 ref 语法糖体验

淮城一只猫 编程技术
阅读量 0 评论量 0

前言

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

展示

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

<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 的后台系统,直接给我整吐了。如果摆在新的提案是这样写的:

<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 以上。

// 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 对象:

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

console.log(x, y)
method()

$raw

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

let count = $ref(0)

const countRef = $raw(count)

console.log(countRef.value)

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

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

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 未来的路是走不远的,语法糖虽好,但不能贪吃,当使用一个语法糖还是尽量理解它最终形成的样子。

喵~