浅析setup sugar:使用与不使用 script setup 的繁杂性对比、具体如何使用 script setup、setup存在的限制(配置项缺失的处理)
一、使用与不使用 script setup 的对比
1、不使用 script setup 的繁杂性
我们之前的组件可能是这样的:
<template>
<div>
<Card>{{msg}}</Card>
</div>
</template>
<script lang="ts">
import { ref, defineComponent } from "vue";
import Card from "./components/Card.vue";
export default defineComponent({
components: {
Card,
},
setup() {
const msg = ref("setup script");
return { msg };
}
});
</script>
这里做了两件事,一个是导入并注册组件,一个是导出一个字符串给template
使用。
如果模板上要使用的这些变量,必须要在 setup 返回的对象中定义。暴露变量必须 return 出来,如果我们内容很多的话,那么这个 setup 就会返回很多值,动辄十几二十行,也是挺繁琐的。有没有更简单的办法,于是 script setup 语法出现。使用这个语法只需要在 script 标签上加上 setup 属性。
2、script setup 使用:启用setup script
之后是这样的
vue3.2 将这个之前的实验功能变为正式功能,在单文件组件中引入了一种新的脚本类型:< script setup >。
<script lang="ts" setup>
import { ref } from "vue";
import Card from "./components/Card.vue";
const msg = ref("setup script");
</script>
这里省去了组件的注册步骤,也没有显式的导出变量的动作。你只需要在script
上配置setup
即可。
<script setup>
import { ref } from 'vue'
// 像在平常的setup中code,但是不需要返回任何变量
const count = ref(0)//在此处定义的count可以直接在模板html中引用
const inc = () => {//函数也可以直接引用,而不用返回
count.value++
}
</script>
<template>
<Foo :count="count" @click="inc" />
</template>
当 <script>
标签具有 setup 属性时,组件在编译的过程中代码运行的上下是 setup() 函数中。所有ES模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。
其实 script setup 就相当于在编译运行是把代码放到了 setup 函数中运行,然后把导出的变量定义到上下文中,并包含在返回的对象中。
二、如何使用 script setup 语法
1、导出变量和方法:在setup script
里面定义的所有变量都会自动导出,非常方便。
2、使用组件:所有的组件导入即可自动注册。
需要注意一点的是:如何定义组件名 => name?
在 script setup 中,引入的组件可以直接使用,无需再通过components
进行注册,并且无法指定当前组件的名字,它会自动以文件名为主。
如果需要定义类似 name 的属性,可以再加个平级的 script 标签,在里面实现即可。
3、使用 props - defineProps:使用 props
需要用到defineProps
来定义,具体用法跟之前的 props
写法类似。
通过 defineProps
指定当前 props 类型的同时,获得上下文的props对象。
在 script中 需要 props[key] 引用,而 template 中可直接调用 key。
<script lang="ts" setup>
import { defineProps } from "vue";
const props = defineProps(['title', 'content']);
</script>
// 给props定义类型:
const props = defineProps({
title: String,
content: {
type: Stirng,
required: true
}
});
// 使用TS的注解的方式:
defineProps<{
title?: string
content: string
}>();
4、使用 emits - defineEmit:使用defineEmit
定义当前组件含有的事件,并通过返回的上下文去执行 emit
使用 defineEmit
对组件里面使用到的事件进行验证和定义,具体用法跟之前一样。
const emit = defineEmit(['onHeaderClick'])
emit('onHeaderClick', 'params')
// 还可以对事件进行验证
const emit = defineEmit({
onHeaderClick: ({title}) => {
if(!title) {
console.warn('Invalid title')
return false
}
return true
}
})
5、使用 context - useContext:使用 useContext
获取上下文。
可以通过useContext
从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrs
和useSlots
import { useContext } from 'vue'
const { slots, attrs } = useContext()
// 获取到的slots attrs跟之前的setup里面的是一样的。
6、使用Slots和Attrs:需要useSlots, useAttrs
<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
7、指令:指令跟组件一样,导入自定注册。
<script setup>
import {color as superColor} from './v-color'
</script>
<template>
<div v-super-color />
</template>
// 导入的 color 重命名为 superColor,并自动映射为指令v-super-color
8、defineExpose API
传统的写法,我们可以在父组件中,通过 ref 实例的方式去访问子组件的内容,但在 script setup 中,该方法就不能用了,setup 相当于是一个闭包,除了内部的 template
模板,谁都不能访问内部的数据和方法。
如果需要对外暴露 setup 中的数据和方法,需要使用 defineExpose API。示例:
<script setup>
import { defineExpose } from 'vue'
const a = 1
const b = 2
defineExpose({
a
}) // 将 a 暴露出去
</script>
三、setup 目前存在的限制
1、配置项的缺失:修改选项配置需要单开一个 script
有时候我们需要更改组件选项,在 setup 中我们目前是无法做到的。我们需要在上方
再引入一个 script
,在上方写入对应的 export
即可。
<script>
export default {
name: 'YourName',
inheritAttrs: false,
customOptions: {},
}
</script>
<script setup>
// your code
</script>
注意:Vue 3 SFC 一般会自动从组件的文件名推断出组件的 name。在大多数情况下,不需要明确的 name 声明。唯一需要的情况是当你需要 <keep-alive>
包含或排除或直接检查组件的选项时,你需要这个名字。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律