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

相关文章

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

JavaScript错误处理避坑指南

《JavaScript错误处理避坑指南》JavaScript错误处理是编程过程中不可避免的部分,它涉及到识别、捕获和响应代码运行时可能出现的问题,本文将详细给大家介绍一下JavaScript错误处理的... 目录一、错误类型:三大“杀手”与应对策略1. 语法错误(SyntaxError)2. 运行时错误(R

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

最新Spring Security实战教程之Spring Security安全框架指南

《最新SpringSecurity实战教程之SpringSecurity安全框架指南》SpringSecurity是Spring生态系统中的核心组件,提供认证、授权和防护机制,以保护应用免受各种安... 目录前言什么是Spring Security?同类框架对比Spring Security典型应用场景传统

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言