Vue3.0 部分实验性 API 将弃用以及script-setup的正式加入

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

最近看了一下 release 记录,发现最新的 2 个小版本对 script-setup 这个新特性改动还算蛮大的,虽然截止至 7 月 2 日的 3.1.4 版本,script-setup 还是处于实验性阶段,但在同一天,尤大在 twitter[2] 上发布了一条推文,预告了它将会在 3.2.0 版本脱离实验状态,正式进入 Vue 3.0 的队伍。


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


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


在此之前,使用第二种方法,是无法指定默认值的(在当时的 RFC 的文档里也有说明无法指定)。如今,这个新的 withDefaults API 可以让你在使用 TS 类型系统时,也可以指定 props 的默认值。它接收两个入参:


参数 类型 含义
props object 通过defineProps传入props
defaultValues object 根据props的key传入默认值


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


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>


相关文章
|
存储 自然语言处理 API
【网安AIGC专题11.1】12 CODEIE用于NER和RE:顶刊OpenAI API调用、CodeX比chatgpt更好:提示工程设计+控制变量对比实验(格式一致性、模型忠实度、细粒度性能)(下)
【网安AIGC专题11.1】12 CODEIE用于NER和RE:顶刊OpenAI API调用、CodeX比chatgpt更好:提示工程设计+控制变量对比实验(格式一致性、模型忠实度、细粒度性能)
108 0
|
3月前
|
JavaScript 前端开发 Linux
【Azure 应用服务】NodeJS Express + MSAL 实现API应用Token认证(AAD OAuth2 idToken)的认证实验 -- passport.authenticate()
【Azure 应用服务】NodeJS Express + MSAL 实现API应用Token认证(AAD OAuth2 idToken)的认证实验 -- passport.authenticate()
|
3月前
|
API Python
【Azure API 管理】API Management 访问限制策略[quota-by-key] 中参数 [renewal-period] 的实验和理解
【Azure API 管理】API Management 访问限制策略[quota-by-key] 中参数 [renewal-period] 的实验和理解
|
3月前
|
JSON 小程序 API
【Azure API 管理】APIM CORS策略设置后,跨域请求成功和失败的Header对比实验
【Azure API 管理】APIM CORS策略设置后,跨域请求成功和失败的Header对比实验
|
4月前
|
机器学习/深度学习 TensorFlow API
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
|
6月前
|
SQL 机器学习/深度学习 人工智能
Web LLM 实验:利用 LLM API 实现 SQL 注入
Web LLM 实验:利用 LLM API 实现 SQL 注入
|
6月前
|
机器学习/深度学习 SQL 人工智能
Web LLM 实验:利用 LLM API 实现命令注入
Web LLM 实验:利用 LLM API 实现命令注入
|
6月前
|
JavaScript API UED
Vue3.0新特性解析与实战:Composition API、Teleport与Suspense
【4月更文挑战第6天】Vue3.0引入了颠覆性的Composition API,通过函数式方法提升代码可读性和复用性,例如`setup()`、`ref`等,便于逻辑模块化。实战中,自定义的`useUser`函数可在多个组件中共享用户信息逻辑。另外,Teleport允许组件渲染到DOM特定位置,解决模态框等场景的上下文问题。再者,Suspense提供异步组件加载的延迟渲染,使用fallback内容改善用户体验。这些新特性显著优化了开发和性能,适应现代Web需求。
121 0
|
API
Vue3.0实现todolist-使用状态管理的api
Vue3.0实现todolist-使用状态管理的api
42 1
|
存储 自然语言处理 API
【网安AIGC专题11.1】12 CODEIE用于NER和RE:顶刊OpenAI API调用、CodeX比chatgpt更好:提示工程设计+控制变量对比实验(格式一致性、模型忠实度、细粒度性能)(中)
【网安AIGC专题11.1】12 CODEIE用于NER和RE:顶刊OpenAI API调用、CodeX比chatgpt更好:提示工程设计+控制变量对比实验(格式一致性、模型忠实度、细粒度性能)
97 0