vue3的script setup特性
本文主要是讲解 与
TypeScript
的基本使用。
是什么?
是在单文件组件 (SFC) 中使用
composition api
的编译时语法糖。
本文使用vue的 3.2.26 版本
1、发展过程
我们先看看 vue3
的发展过程:
Vue3
在早期版本(3.0.0-beta.21
之前)中对composition api
的支持,只能在组件选项setup
函数中使用。
{{ msg }}
-
在 3.0.0-beta.21 版本中增加了
的实验特性。如果你使用了,会提示你
还处在实验特性阶段。
-
在 3.2.0 版本中移除
的实验状态,从此,宣告
正式转正使用,成为框架稳定的特性之一。
{{ msg }}
2、优势
与组件选项 setup
函数对比, 的优点:
-
更少、更简洁的代码,不需要使用
return {}
暴露变量和方法了,使用组件时不需要主动注册了; -
更好的
Typescript
支持,使用纯Typescript
声明props
和抛出事件,不会再像option api
里那么蹩脚了; -
更好的运行时性能;
当然, 也是有自己的缺点的,比如需要学习额外的
API
。
那么 怎么使用呢?有哪些使用要点?与TypeScript如何结合?
3、工具
Vue3
单文件组件 (SFC) 的 TS IDE
支持请用
{{ msg }}
若需要使用 TypeScript
,则将 lang
属性添加到 代码块上,并赋值
ts
。
{{ msg }}
块中的脚本会被编译成组件选项
setup
函数的内容,也就是说它会在每次组件实例被创建的时候执行。
在 声明的顶层绑定(变量、函数、import引入的内容),都会自动暴露给模板,在模板中直接使用。
{{ msg }}
{{ getToken() }}
注意:
-
每个
*.vue
文件最多可同时包含一个块 (不包括
);
-
每个
*.vue
文件最多可同时包含一个块 (不包括常规的
);
5、编译器宏
编译器宏(compiler macros) 有:defineProps
、defineEmits
、withDefaults
、defineExpose
等。
编译器宏只能在 块中使用,不需要被导入,并且会在处理
块时被一同编译掉。
编译器宏必须在 的顶层使用,不可以在
的局部变量中引用。
5.1 defineProps
在 块中是没有组件配置项的,也就是说是没有
props
选项,需要使用 defineProps
来声明 props
相关信息。defineProps
接收的对象和组件选项 props
的值一样。
{{ msg }}
{{ title }}
TS 版本:
{{ msg }}
{{ title }}
从代码中可以发现 TS
写法里 props
没有定义默认值。
Vue3
为我们提供了 withDefaults
这个编译器宏,给 props
提供默认值。
{{ msg }}
{{ title }}
一个需要注意的地方:在顶层声明一个和props
的属性同名的变量,会有些问题。
{{ props.title }}
{{ title }}
所以,和组件选项一样,不要定义和 props
的属性同名的顶层变量。
5.2 defineEmits
一样的,在 块中也是没有组件配置项
emits
的,需要使用 defineEmits
编译器宏声明 emits
相关信息。
// ./components/HelloWorld.vue
{{ msg }}
使用组件:
TS 版本:
// ./components/HelloWorld.vue
{{ msg }}
使用组件:
5.3 defineExpose
在 Vue3
中,默认不会暴露任何在 中声明的绑定,即不能通过模板
ref
获取到组件实例声明的绑定。
Vue3
提供了 defineExpose
编译器宏,可以显式地暴露需要暴露的组件中声明的变量和方法。
// ./components/HelloWorld.vue
{{ msg }}
使用组件:
TS 版本:
// ./components/HelloWorld.vue
{{ msg }}
使用组件:
6、辅助函数
在 中常用的辅助函数
hooks api
,主要有:useAttrs
、useSlots
、useCssModule
,其他的辅助函数还在实验阶段,不做介绍。
6.1 useAttrs
在模板中使用 $attrs
来访问 attrs
数据,与 Vue2
相比,Vue3
的 $attrs
还包含了 class
和 style
属性。
在 中使用
useAttrs
函数获取 attrs
数据。
// ./components/HelloWorld.vue
{{ $attrs.title }}
6.2 useSlots
在模板中使用 $slots
来访问 slots
数据。
在 中使用
useSlots
函数获取 slots
插槽数据。
默认插槽
具名插槽footer
6.3 useCssModule
在 Vue3
中,也是支持 CSS Modules
的,在 上增加
module
属性,即 。
代码块会被编译为
CSS Modules
并且将生成的 CSS 类作为 $style
对象的键暴露给组件,可以直接在模板中使用 $style
。而对于如 具名
CSS Modules
,编译后生成的 CSS 类作为 content
对象的键暴露给组件,即module
属性值什么,就暴露什么对象。
普通style red
默认CssModule pink
默认CssModule pink
具名CssModule blue
具名CssModule blue
注意,同名的CSS Module,后面的会覆盖前面的。
7、使用组件
在组件选项中,模板需要使用组件(除了全局组件),需要在 components
选项中注册。
而在 中组件不需要再注册,模板可以直接使用,其实就是相当于一个顶层变量。
建议使用大驼峰(PascalCase)命名组件和使用组件。
8、组件name
是没有组件配置项
name
的,可以再使用一个普通的 来配置
name
。
// ./components/HelloWorld.vue
{{ total }}
使用:
注意:如果你设置了 lang
属性, 和
的
lang
需要保持一致。
9、inheritAttrs
inheritAttrs
表示是否禁用属性继承,默认值是 true
。
是没有组件配置项 inheritAttrs 的,可以再使用一个普通的
。
./components/HelloWorld.vue
hover一下看title
hover一下看title
10、顶层await支持
中可以使用顶层 await。结果代码会被编译成
async setup()
注意:async setup()
必须与 Suspense
组合使用,Suspense
目前还是处于实验阶段的特性,其 API 可能随时会发生变动,建议暂时不要使用。
11、命名空间组件
在 vue3
中,我们可以使用点语法来使用挂载在一个对象上的组件。
// components/Form/index.js
import Form from './Form.vue'
import Input from './Input.vue'
import Label from './Label.vue'
// 把Input、Label组件挂载到 Form 组件上
Form.Input = Input
Form.Label = Label
export default Form
// 使用:
命名空间组件在另外一种场景中的使用,从单个文件中导入多个组件时:
// FormComponents/index.js
import Input from './Input.vue'
import Label from './Label.vue'
export default {
Input,
Label,
}
// 使用
label
12、状态驱动的动态css
Vue3
中 标签可以通过
v-bind
这一 CSS 函数将 CSS 的值关联到动态的组件状态上。
hello
13、指令
全局指令:
自定义指令:
导入的指令:
更多关于指令,见官方文档
14、Composition Api类型约束
总结
此语法诸多的特性,使单个文件组件更简单!只需要给 script
标签添加一个 setup
属性,那么整个 script
就直接会变成setup
函数,所有顶级变量、函数,均会自动暴露给模板使用(无需再一个个 return了),开发效率将大大的提高!