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

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

AI Toolkit + H100 GPU,一小时内微调最新热门文生图模型 FLUX

上个月,FLUX 席卷了互联网,这并非没有原因。他们声称优于 DALLE 3、Ideogram 和 Stable Diffusion 3 等模型,而这一点已被证明是有依据的。随着越来越多的流行图像生成工具(如 Stable Diffusion Web UI Forge 和 ComyUI)开始支持这些模型,FLUX 在 Stable Diffusion 领域的扩展将会持续下去。 自 FLU

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

javascript中break与continue的区别

在javascript中,break是结束整个循环,break下面的语句不再执行了 for(let i=1;i<=5;i++){if(i===3){break}document.write(i) } 上面的代码中,当i=1时,执行打印输出语句,当i=2时,执行打印输出语句,当i=3时,遇到break了,整个循环就结束了。 执行结果是12 continue语句是停止当前循环,返回从头开始。

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param