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

相关文章

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

PyCharm 接入 DeepSeek最新完整教程

《PyCharm接入DeepSeek最新完整教程》文章介绍了DeepSeek-V3模型的性能提升以及如何在PyCharm中接入和使用DeepSeek进行代码开发,本文通过图文并茂的形式给大家介绍的... 目录DeepSeek-V3效果演示创建API Key在PyCharm中下载Continue插件配置Con

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

一分钟带你上手Python调用DeepSeek的API

《一分钟带你上手Python调用DeepSeek的API》最近DeepSeek非常火,作为一枚对前言技术非常关注的程序员来说,自然都想对接DeepSeek的API来体验一把,下面小编就来为大家介绍一下... 目录前言免费体验API-Key申请首次调用API基本概念最小单元推理模型智能体自定义界面总结前言最

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查