Vue3.0最新动态:script-setup 定稿,部分实验性 API 将弃用

2023-10-21 16:50

本文主要是介绍Vue3.0最新动态:script-setup 定稿,部分实验性 API 将弃用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近一段时间挺忙,对 Vue 3.0 的更新记录看的比较少,今天看了一下 release 记录,发现最新的 2 个小版本对 script-setup 这个新特性改动还算蛮大的,之前的用法都调整了不少。

今天距离上一次发文讨论 script-setup 新特性已经有 4 个多月了(回顾上一篇[1]),虽然截止至 7 月 2 日的 3.1.4 版本,script-setup 还是处于实验性阶段,但在同一天,尤大在twitter[2] 上发布了一条推文,预告了它将会在 3.2.0 版本脱离实验状态,正式进入 Vue 3.0 的队伍。

作者:BASS 网易前端开发工程师

https://zhuanlan.zhihu.com/p/386919557

先简单梳理一下本次定稿下来的一些调整:

useContext API 被弃用

在原先,可以通过该 API 来获取组件的上下文信息,包含了 attrs 、slots 、emit、expose 等父子组件通信数据和方法。

// 导入 useContext 组件
import { useContext } from "vue";// 获取 context
const ctx = useContext();

该 API 将在 3.2 版本之后删除,context 里面的数据,会用新的 useSlots 和 useAttrs API 来代替。

新增 useSlots API 和 useAttrs API

在 useContext API 被删除后,原先的上下文数据,将由这两个新 API 获取到。

useAttrs

顾名思义, useAttrs 可以是用来获取 attrs 数据的(也就是非 props 的属性值)。

// 导入 useAttrs 组件
import { useAttrs } from "vue";// 获取 attrs
const attrs = useAttrs();// attrs是个对象,和 props 一样,需要通过 key 来得到对应的单个 attr
console.log(attrs.msg);

如果当前组件里没有将某个属性指定为 props,那么父组件绑定下来的属性值,都会进入到 attrs 里,通过这个新 API 来拿到。

useSlots

同样,通过 API 的命名也能了解它是用来获取插槽数据的。

但这个 API 对大部分同学来说应该用的比较少,因为大部分 Vue 开发者应该都是用的 SFC 模式(单组件),插槽可以直接在 template 里使用 <slot /> 标签渲染。

所以,我个人觉得这个 API 的目标用户是面向 JSX / TSX 的开发者,简单的用法参考如下:

父组件,可以传入默认插槽和命名插槽:

<template><!-- 子组件 --><ChildTSX><!-- 默认插槽 --><p>I am a default slot from TSX.</p><!-- 默认插槽 --><!-- 命名插槽 --><template #msg><p>I am a msg slot from TSX.</p></template><!-- 命名插槽 --></ChildTSX><!-- 子组件 -->
</template><script setup lang="ts">import ChildTSX from "@cp/context/Child.tsx";
</script>

那么在 JSX / TSX 的子组件,通过 useSlots 来获取父组件传进来的 slots 数据进行渲染:

import { defineComponent, useSlots } from "vue";const ChildTSX = defineComponent({setup() {// 获取插槽数据const slots = useSlots();// 渲染组件return () => (<div>// 渲染默认插槽<p>{slots.default ? slots.default() : ""}</p>// 渲染命名插槽<p>{slots.msg ? slots.msg() : ""}</p></div>);},
});export default ChildTSX;

新增 defineExpose API

在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在 script-setup 模式下,所有数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref 变量获取子组件的数据。

如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,这个操作,就是由 expose 来完成。

expose 也是 context 的一个组件成员,原来的用法,是从 useContext 里导出:

// 导入 useContext 组件
import { useContext } from "vue";// 启用expose组件
const { expose } = useContext();// 定义一个想提供给父组件拿到的数据
const msg: string = "Hello World!";// 显示暴露的数据,才可以在父组件拿到
expose({msg,
});

由于 useContext 会在未来版本里移除,所以新增了 defineExpose API 来实现 expose 的功能。

新的 API 用法:

// 导入 defineExpose 组件
import { defineExpose } from "vue";// 定义数据
const msg: string = "Hello World!";// 暴露给父组件
defineExpose({msg,
});

父组件就可以通过 ref API 去拿到子组件暴露出来的 msg 数据了。

改名 defineEmits API

使用 defineEmits 取代原来的 defineEmit API ,也就是改名了。

好吧,我之前的文章还特地强调了 defineProps 是复数结尾,带有 s,而 defineEmit 没有,如今,都统一了,都是复数形式。

从尤大的更新说明里看,大约只是一个 typo 更新,对比原来的 defineEmit ,目的是使用新的 defineEmits 与标准组件的 emits 命名上更为接近,和 defineProps 也更统一。

╮(╯▽╰)╭ 所以用法方面和原来是没什么区别的:

// 导入 defineEmits 组件
import { defineEmits } from "vue";// 获取 emit
const emit = defineEmits(["say-hi", "chang-name"]);// 调用 emit 打招呼
emit("say-hi", "Hello!");// 调用 emit 改名
emit("chang-name", "Tom");

新增 withDefaults API

说完 emits,经常与之同时出现的 props 也有一些变化,本次是带来了一个全新的 withDefaults API,用于辅助 defineProps 来指定 prop 的默认值。

在以前的文章我有提及到,当你用 TypeScript 编程时,defineProps 有两种类型指定方式:

  1. 通过构造函数进行检查(传统方法)

第一种方式是使用 JavaScript 原生构造函数进行类型规定,使用这种方法时,如果你要限制 props 的类型和默认值,需要通过一个 “对象” 入参来传递给 defineProps,比如:

// 导入 defineProps 组件
import { defineProps } from "vue";// 定义 props
defineProps({name: {type: String,required: false,default: "Petter",},userInfo: Object,tags: Array,
});
  1. 使用类型注解进行检查(TS 专属)

第二种方式是按照 TS 的书写习惯来定义数据类型,这种情况下需要遵循 TypeScript 的类型规范,比如字符串是 string,而不是 String。

// 导入 defineProps 组件
import { defineProps } from "vue";// 对象类型接口
interface UserInfo {id: number;age: number;
}// 定义 props
defineProps<{name: string;phoneNumber: number;userInfo: UserInfo;tags: string[];
}>();

在此之前,使用第二种方法,是无法指定默认值的(在当时的 RFC 的文档里也有说明无法指定)。

如今,这个新的 withDefaults API 可以让你在使用 TS 类型系统时,也可以指定 props 的默认值。

它接收两个入参:

可能缺乏一些官方描述,还是看参考用法可能更直观:

import { defineProps, withDefaults } from "vue";withDefaults(defineProps<{size?: number;labels?: string[];}>(),{size: 3,labels: () => ["default label"],}
);

顶级 await 的支持

不必再配合 async 就可以直接使用 await 了,这种情况下,组件的 setup 会自动变成 async setup 。

<script setup lang="ts">const post = await fetch(`/api/post/1`).then((r) => r.json());
</script>

它转换成标准组件的写法就是:

<script lang="ts">import { defineComponent, withAsyncContext } from "vue";export default defineComponent({async setup() {const post = await withAsyncContext(fetch(`/api/post/1`).then((r) => r.json()));return {post,};},});
</script>

参考资料

以上所有的资料都来自于尤大在 PR 227 的评论通告……传送门:

script setup by yyx990803 · Pull Request #227 · vuejs/rfcsgithub.com[3]

好隐蔽的说,而且原来的 RFC 仓库的文档也删除了,换了新的文档也是找了好久才翻到新的,本文先根据尤大的通告做一波简单的说明,文章首发在博客,只同步在知乎。

Vue3.0 最新动态:script-setup 定稿 部分实验性 API 将弃用 - 程沛权 - 养了三只猫 chengpeiquan.com[4]

后续将会详细更新到 Vue3.0 学习教程与实战案例[5] 里。

参考资料

[1]

回顾上一篇: https://link.zhihu.com/?target=https%3A//chengpeiquan.com/article/vue3-script-setup.html

[2]

twitter: https://link.zhihu.com/?target=https%3A//twitter.com/youyuxi/status/1410744671848910851

[3]

script setup by yyx990803 · Pull Request #227 · vuejs/rfcsgithub.com: https://link.zhihu.com/?target=https%3A//github.com/vuejs/rfcs/pull/227%23issuecomment-870105222

[4]

Vue3.0 最新动态:script-setup 定稿 部分实验性 API 将弃用 - 程沛权 - 养了三只猫 chengpeiquan.com: https://link.zhihu.com/?target=https%3A//chengpeiquan.com/article/vue3-script-setup-finalization.html

[5]

Vue3.0 学习教程与实战案例: https://link.zhihu.com/?target=https%3A//vue3.chengpeiquan.com/

这篇关于Vue3.0最新动态:script-setup 定稿,部分实验性 API 将弃用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/255675

相关文章

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的