跳到主要内容位置

Vue 3 的 script setup 特性体验,进一步减少代码量

Vue setup script 进一步简化了 vue composition api 的代码,不用每次都导出一个只含有 setup() 函数的对象了,而是直接把函数的内容写在 <script/> 标签中,只需要给 <script /> 加上 setup 属性即可。

Vue script setup 虽然已经包含在最新版的 vue 中了,但仍然是实验特性,如果是使用 vite 2.0 创建的项目,那么它的示例代码就已经使用 vue script setup 了。

与 setup() 函数的区别

接下来看一下它与普通 setup() 有什么区别。

首先是 <script /> 标签加上了 setup 属性,它里边的代码可以直接视为在 setup() 函数中编写的,同时,import 语句也可以使用,仍然需要放在最上方。

<script setup>
import SomeComponent from "./components/SomeComponent.vue";
</script>

在 script setup 里边定义的变量、函数和导入的模块可以直接在 <template /> 模板中使用:

<template>
<SomeComponent>{{ msg }}</SomeComponent>
</template>
<script setup>
import SomeComponent from "./components/SomeComponent.vue";
const msg = "hello";
</script>

其实它编译后的代码类似于这样:

import SomeComponent from "./components/SomeComponent.vue";
function setup() {
const msg = "hello";
return () => {
// <template /> 的作用域相当于在这里
// 可以访问 msg
return h(SomeComponent, msg);
};
}

可以看到,<template /> 标签其实就像是直接从 setup() 函数中返回出去的 render() 函数,如果把 h() 函数的调用改成 JSX 形式的话,其实跟 React 也几乎是一样了。

访问属性

由于使用了 script setup 之后不能访问 setup() 函数的参数了,如果要获取父组件传递来的属性,那么需要使用 defineProps 函数,可以从 vue 库中导入进来,它接收一个对象作为参数,对象的 key 为属性名,value 为属性的类型,也可以是一个对象,包含默认值、类型、是否为必须的等更丰富的信息。最后 defineProps 会返回一个对象,可以通过它的属性访问 props。

<template>
<div>
<p>{{ a }}</p>
<p>{{ b.someProp }} </p>
</div>
</template>
<script setup>
import { defineProps } from "vue";
const props = defineProps({
a: Number,
b: {
type: Object,
default: {},
required: true
}
});
</script>

触发事件

使用 script setup 也不能通过访问 setup 函数中的 context 参数来触发事件,这时可以用 defineEmit 来实现,它接收一个数组作为参数,定义当前组件将会触发的自定义事件:

<script setup>
import {defineEmit} from "vue"; const emit = defineEmit(['click', 'change'])
</script>

最后,就可以使用返回的 emit 触发事件了:

<template>
<button @click="emit('click', 10)">点击</button>
</template>

获取 Context

获取 context 信息可以使用 useContext() 函数,也是从 vue 库中导入进来,里边可以获取 slots 和 attrs 等信息:

<script setup>
import {useContext} from "vue"; const {(slots, attrs)} = useContext()
</script>

问题

在实际使用 script setup 时,有一些小的问题需要注意。

第一是会发现在 template 用到但是没在 script 用到的变量可能会提示 unused,这个没有实际影响,不过看起来可能会有点难受。

第二是 defineProps() 和 defineEmits() 定义的属性和事件不能访问 script setup 中定义的变量,因为传递给这两个函数的参数会提升到模块顶级作用域中,而不是在 setup() 函数中,同样的,import 语句也会提升到模块顶级作用域中。

好了,这些就是我在使用 setup script 上的一些经验,如果有帮助,请三连,想更好的学前端,请关注峰华前端工程师,感谢观看!

提示

一系列的课程让你成为高级前端工程师。课程覆盖工作中所有常用的知识点和背后的使用逻辑,示例全部都为工作项目简化而来,学完即可直接上手开发!

即使你已经是高级前端工程师,在课程里也可能会发现新的知识点和技巧,让你的工作更加轻松!

《React 完全指南》课程,连载中现只需 48 元(领取优惠券)点击查看详情。

《Vue 3.x 全家桶完全指南与实战》课程,包括 Vue 3.x、TypeScript、Vue Router 4.x、Vuex 4.x 所有初级到高级的语法特性详解,让你完全胜任 Vue 前端开发的工作。点击查看详情。

《React即时通信UI实战》课程,利用 Storybook、Styled-components、React-Spring 打造属于自己的组件库。

《JavaScript 基础语法详解》本人所著图书,包含 JavaScript 全面的语法知识和新特性, 可在京东、当当、淘宝等各大电商购买