上一篇说了 DefineOptions、defineModel、Props 的响应式解构和从外部导入类型 这几个新功能,但是没有说Generic、defineSlots等,这是因为还没有完全搞清楚可以用在什么地方。折腾了几天终于弄清楚了。

这还要从 TS 的泛型说起。

泛型的目的和意义

泛型仅仅只是表达传啥都行吗?当然不是,因为js原生就支持“泛型”,本来就啥都可以传的。

泛型的目的是——约束!泛型相当于制定了一个白名单,名单里面的类型可以传,不在名单里面的不可以传。

TS 的泛型可以帮助我们更准确的推断类型,从而在编写代码的时候,可以有更准确的提示和提供验证依据。

泛型组件(Generic Component)

组件的props可以设置各种类型,那么如果想用泛型的话,要如何设置呢?这就需要使用 Generic:

<script setup lang="ts" generic="T extends {name: string} ">

  const props = defineProps<{
list: T[], // 泛型的方式
list2: number[], // 只能是 number 类型的数组
list3: Array<any>, // 任意类型的数组
name: string,
person: {
name: string
}
}>() console.log('props-ts:\n', props)

这里定义了几个属性,第一个使用了泛型,第二个是 number[],第三个是任意类型的数组。

我们来看看不同类型的提示信息:

  • Array<any> 提示的时候,无法获知具体的类型。

  • number[] 必须和设置的类型完全一致。

  • T[] 可以根据传入的类型做出对应的提示

    • 传入 {name: string}

    • 传入 {name: string, age: number}

    • 类型不匹配的提示

对比一下,我们可以发现,使用泛型可以准确的推断类型,在模板里面可以有更准确的提示,如果类型不合格,可以有提示信息。

这样在编写代码的时候可以避免低级错误。

defineSlots

defineSlots 是做什么的呢,是定义插槽还是获取插槽?准确的说,是定义作用域插槽props的类型(支持泛型),然后返回父组件传入的插槽。

在 setup 里面定义插槽的类型

在组件里面定义两个插槽,一个是匿名插槽,一个是作用域插槽(col),

定义一个 list 的属性,传入一个数组,然后遍历这个数组,创建一组列表,列表内使用作用域插槽。

通过作用域插槽的props把数组元素传递给父组件:(好像有点绕)

<script setup lang="ts" generic="T extends Object ">

  const props = defineProps<{
list: T[], // 泛型的方式
}>() const slot = defineSlots<{
default(props: any): any,
col(props:
{
row: T,
index: number
}): any
}>()
console.log('slot:\n', slot)
<template>
<!--匿名插槽-->
<slot></slot>
<div v-for="(item, index) in list" :key="index">
<!--作用域插槽-->
<slot name="col" :row="item" :index="index" ></slot>
</div>
</template>

父组件里使用的方法

<script setup lang="ts">
import { reactive } from 'vue'
// 加载子组件
import ts from './20-ts.vue'
// 定义数组
const list2 = reactive([
{
name: '11',
age: 10
},
{
name: '66',
age: 10
}
])
</script>
<template>
<ts :list="list2" > <!--传入数据列表-->
<h1>测试插槽</h1>
<template #col="{ item, index }"> <!--用解构的方式获取-->
序号:{{ index }}<br> <!--其实这里是循环-->
内容:{{ item }}
</template>
</ts>
</template>

UI库里的 table 组件一般都会支持这样的插槽,以便于灵活设置列表,比如 el-table 的 el-table-column:

(来自官网示例代码)

<el-table :data="tableData" style="width: 100%">
<el-table-column label="日期" width="180">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-icon><timer /></el-icon>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</div>
</template>
</el-table-column>
...
</el-table>

这里的 default 就是一个匿名作用域插槽,可以通过scope.row获得每一行的数据。

defineEmits

defineEmits 是定义事件的一种快捷表达方式,也是一种语法糖,这个和 defineModel 有重合的地方,那就是 v-model 的 update:modelValue 的部分。

话说,组件需要事件吗?以前是事件驱动,现在是数据驱动,或者说是状态驱动。以前监听事件,现在只需要监听状态的变化即可,从dom脱离出来。

好吧,其实我基本已经不使用 emit 了,感觉似乎并不需要了。

参考资料

Generic component enhancements - Discussion #436:

unplugin-vue-define-options - npm: https://www.npmjs.com/package/unplugin-vue-define-options

Announcing Vue 3.3 | The Vue Point: https://blog.vuejs.org/posts/vue-3-3

Vue 3.3 主要新特性详解 - 三咲智子 Kevin Deng: https://xlog.sxzz.moe/vue-3-3

5 Vue3.3 发布:十分钟速递

6 官方帮助文档

7 elementPlus

Vue3.3 的新功能的体验(下):泛型组件(Generic Component) 与 defineSlots的更多相关文章

  1. 4.0 SDK Workshop 纪实:一起体验多人、多屏幕共享新功能

    在本月初,声网发布了 RTC Native SDK 4.0 版本.该版本提供了更高的开发灵活度,可明显提升实时场景开发效率,并让第三方插件开发更容易.上周六(8月20日),我们组织了一场小型的线下 W ...

  2. 个人官网第8次升级(新功能、用户体验、修复bug、系统优化)

    1.新功能. 操作日志和搜索日志的Excel报表下载. 2.用户体验. 如果是通过搜索,进入到一篇内容, 搜索关键词需要高亮. 比如,搜索"程序员"出现若干内容链接,打开链接的页面 ...

  3. VS2017十五项新功能体验

    Visual Studio 2017十五项新功能体验 Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP ...

  4. 地图SDK全面升级 – 数十项新功能及优化等你来体验

    腾讯位置服务地图SDK是一套提供多种地理位置服务的应用程序接口.通过调用该接口,开发者可以在自己的应用中加入地图相关的功能(如地图展示.标注.绘制图形等),轻松访问腾讯地图服务和数据,构建功能丰富.交 ...

  5. Visual Studio 2017十五项新功能体验

    Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP 2017技术峰会将于这个周末(3.17)在北京举办,由 ...

  6. 05-TypeScript中的方法新功能(下)

    再TypeScript中,方法还有一些新功能能够让我们更好的控制方法执行. 1.Generator方法: yield关键字用于控制方法在执行的时候暂停住,后续方法调用方又可以从暂停的地方继续执行,这种 ...

  7. 3.0.0 alpha 重磅发布!九大新功能、全新 UI 解锁调度系统新能力

    2022 年 4 月 22 日,Apache DolphinScheduler 正式宣布 3.0.0 alpha 版本发布!此次版本升级迎来了自发版以来的最大变化,众多全新功能和特性为用户带来新的体验 ...

  8. 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能

    前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...

  9. 【开源】OSharp3.0框架解说系列:新版本说明及新功能规划预览

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  10. 微信小程序0.11.122100版本新功能解析

    微信小程序0.11.122100版本新功能解析   新版本就不再吐槽了,整的自己跟个愤青似的.人老了,喷不动了,把机会留给年轻人吧.下午随着新版本开放,微信居然破天荒的开放了开发者论坛.我很是担心官方 ...

随机推荐

  1. 翟佳:StreamNative 组织构建之路丨声网开发者创业讲堂 • 第 5 期

    前言 翟佳,StreamNative 联合创始⼈,Apache Pulsar PMC 成员与 Committer.之前任职于 EMC,担任统⼀存储部⻔技术负责⼈. 在声网开发者创业讲堂 • 第 5 期 ...

  2. 基于PaddleOCR的多视角集装箱箱号检测识别

    基于PaddleOCR的多视角集装箱箱号检测识别 一.项目介绍 集装箱号是指装运出口货物集装箱的箱号,填写托运单时必填此项.标准箱号构成基本概念:采用ISO6346(1995)标准 标准集装箱箱号由1 ...

  3. 深入消息队列MQ,看这篇就够了!

    大厂面试爱问消息队列 MQ. 因为消息队列MQ,既是大型分布式系统不可缺少的中间件,也是高并发系统的基石中间件. 如果你想要快速掌握消息队列 MQ 最内核的知识,以及消息队列MQ的主流应用场景.主流产 ...

  4. MarkdownStudy01markdown用法

    一级标题 二级标题 三级标题 字体 Hello,Word! Hello,Word! Hello,Word! Hello,Word! 引用 好好学Java 分割线 图片 超链接 点击跳转 列表 A B ...

  5. window身上的方法 弹出框/打开和关闭

    window身上的方法内置函数 alert() parseInt() parseFloat() setInterval(); setTimeout(); clearTimeout(); clearIn ...

  6. buuctf-RE-SimpleRev

    IDA 打开 将main函数反编译为C代码 1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) ...

  7. 企业什么喜欢做电视看板,电视看板浏览网页的必备工具 电视看板浏览器 电视看板自动打开网页 电视看板必备APP

    企业喜欢做电视看板主要是因为它可以提供以下几个方面的优势: 增强企业形象:电视看板可以将企业的信息和广告以更加生动.直观的方式呈现出来,提高企业形象和知名度. 提高工作效率:电视看板可以在企业内部作为 ...

  8. Django笔记十八之save函数的继承操作和指定字段更新等实例方法

    本文首发于微信公众号:Hunter后端 原文链接:Django笔记十八之save函数的继承操作和指定字段更新等实例方法 这篇笔记主要介绍 Django 一些实例方法. 什么是 实例,我们知道通过fil ...

  9. Unity学习笔记02 —— C#语法

    C#语法 控制台 Console Console.WriteLine(); Console.ReadLine(); 随机数 Random Random random = new Random(); r ...

  10. 四月十七日Java基础知识点

    1.默认构造方法:如果class前面有public修饰符,则默认的构造方法也会是public的.由于系统提供的默认构造方法往往不能满足需求,所以用户可以自己定义类的构造方法来满足需要,一旦用户为该类定 ...