当前位置:首页> 行业快讯 >

Vue3.3 的新功能的体验(下):泛型组件(Generic Component) 与 defineSlots_全球新要闻

时间:2023-05-26 13:57:24    来源:博客园

上一篇说了 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, // 任意类型的数组    name: string,    person: {      name: string    }  }>()  console.log("props-ts:\n", props)

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

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

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

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)
父组件里使用的方法
<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>

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

(来自官网示例代码)

                  ...  

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

defineEmits

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

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

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

参考资料

1Generic component enhancements - Discussion #436:

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

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

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

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

6 官方帮助文档

7 elementPlus

标签:

青藏高原最大中心城市发现多种珍稀野生动物影像

中新网西宁5月25日电 (记者 孙睿)中国科学院西北高原生物研究所专家连新明25日向中新网记者透露,通过近一年来的观测,在青藏高原最大中

2022-05-25

湖北一男子在赣病逝 家属捐献器官挽救3人

中新网南昌5月25日电 (记者 吴鹏泉)江西省红十字会24日消息,湖北一男子在江西南昌因病逝世,家属在悲痛中捐献其器官,挽救了3名重症患者

2022-05-25

湖北云梦全县域恢复实施常态化疫情防控措施

(抗击新冠肺炎)湖北云梦全县域恢复实施常态化疫情防控措施 中新网孝感5月25日电 据湖北孝感市云梦县新冠肺炎疫情防控指挥部通告,该县全

2022-05-25

手语律师唐帅:让法治阳光照亮无声世界

奋进新征程 建功新时代·我们的新时代丨手语律师唐帅:让法治阳光照亮无声世界 新华社重庆5月24日电 题:手语律师唐帅:让法治阳光照亮

2022-05-25

中国援柬中医张大武:升华中柬医患友谊的“关键钥匙”

中新网金边5月25日电 (记者 欧阳开宇)“大医博学,厚德济民”——中国中医科学院西苑医院院训。在张大武看来,这句话也是一把升华中柬医

2022-05-25

(中国这十年·吾乡)“邂逅雪豹”带热高原小镇

记者 李江宁 摄 " >

2022-05-25

“但凡有可能,就去做好它”

西北工业大学网络空间安全学院党总支书记王震—— “但凡有可能,就去做好它”(奋斗者正青春) 在西北工业大学网络空间安全学院,党总支书记王

2022-05-25

上海通报嘉定区1例本土无症状感染者排查情况 一地列为中风险地区

中新网5月25日电 据“上海发布”微信公众号消息,5月25日上午举行的上海市疫情防控工作新闻发布会上,上海市卫生健康委副主任赵丹丹介绍,

2022-05-25

上海嘉定区公布1例无症状感染者所涉及区域和场所

中新网5月25日电 据“上海发布”微信公众号消息,5月25日上午举行的上海市疫情防控工作新闻发布会上,上海嘉定区副区长王浩介绍:5月24日

2022-05-25

在家里坐着就能赚到养老钱?37名老人落入高额返现陷阱

37名老人落入高额返现陷阱 本报讯(记者倪建军 通讯员黄洪福 张建军)老年人在家里坐着就能赚到养老钱!只要办理店铺的会员卡成为会员,凡一

2022-05-25