提前看看Vue 3.5

97 阅读2分钟

翻译自 What’s Coming in Vue 3.5

Vue 3.5 将带来哪些新特性?

Vue.js 正在为即将推出的新次版本 Vue 3.5 做准备。该版本(目前处于 Alpha 阶段)带来了一系列增强功能、新特性和重要改动,以提升开发和用户体验。以下是 Vue 3.5 的一些亮点,基于官方的变更日志以及我们朋友 Michael 和 Alex 在 DejaVue 播客中与 Evan 的访谈内容。

1. 响应式 Props 解构

响应式 props 解构已经处于实验阶段约一年时间,而在 3.5 版本中将作为稳定特性发布。此功能允许你从 defineProps 宏中解构 props,同时保持响应性。

import { watchEffect } from 'vue'

const { count } = defineProps(['count'])

watchEffect(() => {
  // 每当父组件的 count prop 发生变化时,这里都会记录
  console.log(count)
})

Evan 表示:“几乎每个在实际项目中使用过响应式 props 解构的开发者都给予了积极的反馈。他们都喜欢这个功能……希望看到它稳定下来。”

对于不希望使用此功能的开发者,可以通过以下标志将其关闭。

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

2. useTemplateRef

目前声明模板引用的方式如下:

<script setup>
// 首先定义一个值为 undefined 或 null 的 ref,并将结果变量命名为你想要的名称
const divEl = ref();
</script>

<template>
  <!-- 然后在模板中使用相同的名称作为 ref 属性 -->
  <div ref="divEl"></div>
</template>

这种方式有两个问题:

  1. 有时会令人困惑。divEl 是响应式数据还是 DOM 元素?如果你有命名模板引用的约定这还不算糟,但最终你需要在模板中查看匹配的 ref= 以确保。
  2. 这限制了只能在组件的 script setup 部分定义模板引用。这意味着需要访问 DOM 元素的 composable 必须将模板引用作为参数。

现在,使用 useTemplateRef 可以解决这两个问题。

// MyComposable
export const useMyComposable = (options = {
  templateRef: 'el'
}) => {
  // 因为函数名称的原因,很明显这是一个模板引用
  const theEl = useTemplateRef(options.templateRef);
}

// MyComponent
<script setup>
// 无需在组件中定义模板引用
// 这可以由 composables 来完成
useMyComposable()
useMyComposable({ templateRef: 'el2' })
</script>
<template>
  <div ref="el"></div>
  <div ref="el2"></div>
</template>

3. useId

新的 useId 工具 composable 返回一个在服务器渲染和客户端渲染中都稳定的唯一 ID(减少了一个可能导致应用程序水合不匹配的因素)。这对于表单元素属性如 forid 以及无障碍属性非常有用。

<!--MyCustomInput-->
<script setup>
defineProps({
  label: String,
  help: String,
  //...
})

const inputId = useId();
const helpTextId = useId();
</setup>
<template>
  <label :for="inputId">{{label}}</label>
  <input :id="inputId" :aria-describedby="helpTextId"/>
  <p :id="helpTextId">{{ help }}</p>
</template>

总结

这些只是 Vue 3.5 次版本的一些亮点。其他错误修复和功能包括:

  • 更好的 prop 类型推断
  • 支持直接在 Transition 中嵌套 Teleport
  • app.onUnmount() 用于注册清理函数
  • failSilently 参数用于 onScopeDispose
  • 以及更多!