Vue3.3 编译宏

image.png

Vue 3.3新增了一些语法糖和宏,包括泛型组件、defineSlots、defineEmits、defineOptions

defineProps

  • 父子组件传参
<template><div><Child name="xiaoman"></Child></div>
</template><script lang='ts' setup>import Child from './views/child.vue'
</script>
<style></style>

子组件使用defineProps接受值

<template><div>{{ name }}</div>
</template><script  lang='ts' setup>defineProps({name: String})
</script>
  • 使用TS字面量模式
<template><div>{{ name }}</div>
</template><script  lang='ts' setup>defineProps<{name:string}>()
</script>
  • Vue3.3 新增 defineProps 可以接受泛型
 <Child :name="['xiaoman']"></Child>//-------------子组件-----------------<template><div>{{ name }}</div>
</template><script generic="T"  lang='ts' setup>defineProps<{name:T[]}>()
</script>

defineEmits

  • 父组件
<template><div><Child @send="getName"></Child></div>
</template><script lang='ts' setup>import Child from './views/child.vue'const getName = (name: string) => {console.log(name)}
</script>
<style></style>

子组件常规方式派发Emit

<template><div><button @click="send">派发事件</button></div>
</template><script  lang='ts' setup>
const emit = defineEmits(['send'])
const send = () => {// 通过派发事件,将数据传递给父组件emit('send', '我是子组件的数据')
}
</script>

子组件TS字面量模式派发

<template><div><button @click="send">派发事件</button></div>
</template><script  lang='ts' setup>
const emit = defineEmits<{(event: 'send', name: string): void
}>()
const send = () => {// 通过派发事件,将数据传递给父组件emit('send', '我是子组件的数据')
}
</script>

Vue3.3 新写法更简短

<template><div><button @click="send">派发事件</button></div>
</template><script  lang='ts' setup>
const emit = defineEmits<{'send':[name:string]
}>()
const send = () => {// 通过派发事件,将数据传递给父组件emit('send', '我是子组件的数据')
}
</script>

defineExpose

没变化

defineExpose({name:"张三"
})

defineSlots

  • 父组件
<template><div><Child :data="list"><template #default="{item}"><div>{{ item.name }}</div></template></Child></div>
</template>
<script lang='ts' setup>
import Child from './views/child.vue'
const list = [{name: "张三"},{name: "李四"},{name: "王五"}
]
</script>
<style></style>

子组件 defineSlots只做声明不做实现 同时约束slot类型

<template><div><ul><li v-for="(item,index) in data"><slot :index="index" :item="item"></slot></li></ul></div>
</template><script generic="T"  lang='ts' setup>
defineProps<{data: T[]
}>()
defineSlots<{default(props:{item:T,index:number}):void
}>()
</script>

defineOptions

  • 主要是用来定义 Options API 的选项

常用的就是定义name 在seutp 语法糖模式发现name不好定义了需要在开启一个script自定义name现在有了defineOptions就可以随意定义name了

defineOptions({name:"Child",inheritAttrs:false,
})

defineModel

由于该API处于实验性特性 可能会被删除暂时不讲

 warnOnce(`This project is using defineModel(), which is an experimental ` +`feature. It may receive breaking changes or be removed in the future, so ` +`use at your own risk.\n` +`To stay updated, follow the RFC at https://github.com/vuejs/rfcs/discussions/503.`)

源码解析

  • core\packages\compiler-sfc\src\script\defineSlots.ts
export function processDefineSlots(ctx: ScriptCompileContext,node: Node,declId?: LVal
): boolean {//是否调用了defineSlotsif (!isCallOf(node, DEFINE_SLOTS)) {return false}//是否重复调用了defineSlotsif (ctx.hasDefineSlotsCall) {ctx.error(`duplicate ${DEFINE_SLOTS}() call`, node)}//函数将 ctx 对象的 hasDefineSlotsCall 属性设置为 true,表示已经调用了 DEFINE_SLOTS 函数ctx.hasDefineSlotsCall = true//然后函数检查传递给 DEFINE_SLOTS 函数的参数个数是否为零,如果不是,则函数抛出错误,指示 DEFINE_SLOTS 函数不接受参数。if (node.arguments.length > 0) {ctx.error(`${DEFINE_SLOTS}() cannot accept arguments`, node)}
//接下来,如果函数接收到了一个可选的表示插槽定义的标识符的节点对象,
//则函数使用 ctx.s.overwrite 
//方法将该节点对象替换为一个表示使用插槽的帮助函数的调用if (declId) {ctx.s.overwrite(ctx.startOffset! + node.start!, //开始位置ctx.startOffset! + node.end!, //结束位置`${ctx.helper('useSlots')}()` //替换的内容 此时就拥有了类型检查)}return true
}
  • core\packages\compiler-sfc\src\script\defineOptions.ts
export function processDefineOptions(ctx: ScriptCompileContext,node: Node
): boolean {//是否调用了defineOptionsif (!isCallOf(node, DEFINE_OPTIONS)) {return false}//是否重复调用了defineOptionsif (ctx.hasDefineOptionsCall) {ctx.error(`duplicate ${DEFINE_OPTIONS}() call`, node)}//defineOptions()不能接受类型参数if (node.typeParameters) {ctx.error(`${DEFINE_OPTIONS}() cannot accept type arguments`, node)}//defineOptions()必须接受一个参数if (!node.arguments[0]) return true//函数将 ctx 对象的 hasDefineOptionsCall 属性设置为 true,表示已经调用了 DEFINE_OPTIONS 函数ctx.hasDefineOptionsCall = true//函数将 ctx 对象的 optionsRuntimeDecl 属性设置为传递给 DEFINE_OPTIONS 函数的参数ctx.optionsRuntimeDecl = unwrapTSNode(node.arguments[0])let propsOption = undefinedlet emitsOption = undefinedlet exposeOption = undefinedlet slotsOption = undefined//遍历 optionsRuntimeDecl 的属性,查找 props、emits、expose 和 slots 属性if (ctx.optionsRuntimeDecl.type === 'ObjectExpression') {for (const prop of ctx.optionsRuntimeDecl.properties) {if ((prop.type === 'ObjectProperty' || prop.type === 'ObjectMethod') &&prop.key.type === 'Identifier') {if (prop.key.name === 'props') propsOption = propif (prop.key.name === 'emits') emitsOption = propif (prop.key.name === 'expose') exposeOption = propif (prop.key.name === 'slots') slotsOption = prop}}}//禁止使用defineOptions()来声明props、emits、expose和slotsif (propsOption) {ctx.error(`${DEFINE_OPTIONS}() cannot be used to declare props. Use ${DEFINE_PROPS}() instead.`,propsOption)}if (emitsOption) {ctx.error(`${DEFINE_OPTIONS}() cannot be used to declare emits. Use ${DEFINE_EMITS}() instead.`,emitsOption)}if (exposeOption) {ctx.error(`${DEFINE_OPTIONS}() cannot be used to declare expose. Use ${DEFINE_EXPOSE}() instead.`,exposeOption)}if (slotsOption) {ctx.error(`${DEFINE_OPTIONS}() cannot be used to declare slots. Use ${DEFINE_SLOTS}() instead.`,slotsOption)}return true
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/14292.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

装饰器模式:通过剖析Java IO类库源码学习装饰器模式

我们通过剖析Java IO类的设计思想&#xff0c;再学习一种新的结构型模式&#xff0c;装饰器模式。它的代码结构跟桥接模式非常相似&#xff0c;不过&#xff0c;要解决的问题却大不相同。 Java IO类库非常庞大和复杂&#xff0c;有几十个类&#xff0c;负责IO数据的读取…

【高级程序设计语言C++】类与对象

2.1类的定义2.1.1 类的两种定义方式2.1.2 类的访问限定符2.1.3 C中的struct和class的区别是什么&#xff1f;2.1.4 类的实例化2.1.5 计算类对象的大小2.1.6 this指针 2.2 类的6个默认成员函数2.2.1 构造函数2.2.2 析构函数2.2.3 拷贝构造函数2.2.4 赋值运算符重载2.2.5 取地址及…

Linux 网络延迟排查方法详解

概要 在 Linux 服务器中&#xff0c;可以通过内核调优、DPDK 以及 XDP 等多种方式提高服务器的抗攻击能力&#xff0c;降低 DDoS 对正常服务的影响。在应用程序中&#xff0c;可以使用各级缓存、WAF、CDN 等来缓解 DDoS 对应用程序的影响。 但是需要注意的是&#xff0c;如果 …

液滴接触角边界曲线识别—巧用Ovito

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

Protobuf类型定义

"都甩掉吧&#xff0c;我们的世界一定会更美好&#xff01;其他不重要&#xff01;" 前面呢&#xff0c;我们讲了如何在Linux环境下安装Protobuf所需的库&#xff0c;那么本篇的着眼点在于Protobuf的编写以及语法规则。 什么是proto3? ProtocolBuffers语⾔版本3&am…

【Python实战】Python采集王者皮肤图片

前言 我们上一篇介绍了,如何采集王者最低战力,本文就来给大家介绍如何采集王者皮肤,买不起皮肤,当个桌面壁纸挺好的。下面,我和大家介绍如何获取数据。 环境使用 python 3.9pycharm模块使用 requests模块介绍 requests requests是一个很实用的Python HTTP客户端库,…

[期末网页作业]-精仿华为官网10个网页(html+css+js)

经过漫长的期末考试季节&#xff0c;我成功地完成了一个华为官网的仿写项目&#xff0c;并且非常高兴地与大家分享。这个项目包含了10个页面&#xff0c;每一个页面都经过了精心的设计和努力的填充。 首先&#xff0c;我注重了页面的整体布局与设计。借鉴了华为官网的风格&…

一文搞懂常见的加密算法

加密算法在互联网技术领域中几乎是无处不在&#xff0c;而密码学也是网络安全的重要基础&#xff0c;这篇文章我们就一起来学习下常见的加密算法。 1 为什么要研究加密算法&#xff1f; 在技术方面&#xff0c;加密算法的研究具有重要的意义&#xff0c;主要体现在以下几个方…

FreeRTOS实时操作系统(十二)事件标志组

系列文章目录 文章目录 系列文章目录事件标志组事件标志组API函数实验测试 事件标志组 事件标志位&#xff1a;用一个位来表示事件是否可以发生。 事件标志组是一组事件标志位的集合 特点&#xff1a; 1.每一个位表示一个事件&#xff08;高8位不是&#xff09; 2.每一位事件…

ncnn源码阅读(二)----网络模型结构和权重参数的加载

网络模型结构和权重参数的加载 ncnn推理框架中把模型的结构和权重参数分为两个文件进行存储&#xff0c;实现了结构和权重的分离。在xxx.param中存储了模型的结构信息&#xff0c;在xxx.bin中存储了模型的权重信息。xxx.param的文件结构如下&#xff1a; layer&#xff1a;描…

开源防病毒引擎ClamAV

本文软件是应网友 Windows 的要求折腾的&#xff1b; 什么是 ClamAV &#xff1f; ClamAV 是一个开源 ( GPLv2 ) 反病毒工具包&#xff0c;专为邮件网关上的电子邮件扫描而设计。它提供了许多实用程序&#xff0c;包括灵活且可扩展的多线程守护程序、命令行扫描程序和用于自动数…

进程池线程池实现TCP高性能并发通信

进程池线程池实现TCP高性能并发通信 使用进程池与线程池实现并发服务&#xff0c;为多个客户进行接收和发送消息的服务 代码实现 # 导入进程池 from multiprocessing import Pool, cpu_count # 导入线程池 from multiprocessing.pool import ThreadPool from socket import …