里面的代码会被编译成组件 setup() 函数的内容。这意味着与普通的 只在组件被首次引入的时候执行一次不同, 中的代码会在每次组件实例被创建的时候执行。
使用setup函数
- import { ref } from 'vue'
- export default {
- name: 'Home',
- setup () {
- const num = ref(1)
- return { num }
- }
- }
使用<script setup>
- import { ref } from 'vue'
- const num = ref(1)
so ~ 你是喜欢两行定义一个变量还是写成好多好多行,注意 当使用 的时候,任何在 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用
使用setup函数
- <div class="home">
- <h1>使用了setup函数h1>
- <h2> {{lowercase1(name)}}h2>
- div>
- <script>
- import { ref } from 'vue'
- import { lowercase } from '@/utils/lowercase.js'
- export default {
- setup () {
- const name = ref('MYNAME')
- const lowercase1 = lowercase
- return { name, lowercase1 }
- }
- }
- script>
使用<script setup>
- <div class="about">
- <h1>使用了script setuph1>
- <h2>1.使用变量 {{lowercase(name)}}h2>
- div>
-
- <script setup>
- import { lowercase } from '@/utils/lowercase.js'
- import { ref } from 'vue'
- const name = ref('MYNAME')
- script>
不需要在定义成一个方法啦 直接使用
使用setup函数
- import Hello from '@/components/HelloWorld'
- export default {
- components: {
- Hello
- }
- }
使用<script setup>
- import Hello from '@/components/HelloWorld'
不需要在component 在注册了
不使用<script setup>
- <h1 v-onceClick>使用了setup函数h1>
- <script>
-
- export default {
- directives: {
- onceClick: {
- mounted (el, binding, vnode) {
- console.log(el)
- }
- }
- },
-
- }
- script>
使用<script setup>
- <h1 v-my-Directive>使用了script setuph1>
- <script setup>
- const vMyDirective = {
- beforeMount: (el) => {
- console.log(el)
- // 在元素上做些操作
- }
- }
- script>
全局注册的自定义指令将正常工作。本地的自定义指令在 中不需要显式注册,但他们必须遵循 vNameOfDirective 这样的命名规范
<Com :num="100">Com>
使用setup函数
- export default {
- props: {
- num: {
- type: Number,
- default: 1
- }
- },
- setup (props) {
- console.log(props)
- }
- }
使用<script setup>
- import { defineProps } from 'vue'
- // eslint-disable-next-line no-unused-vars
- const props = defineProps({
- num: {
- type: Number,
- default: 1
- }
- })
使用setup函数
- export default {
- setup (props, context) {
- const sendNum = () => {
- context.emit('sendNum', 1200)
- }
- return { sendNum }
- }
- }
使用<script setup>
- import { defineProps, defineEmits } from 'vue'
- const emit = defineEmits(['submit'])
- const sendNum = () => {
- emit('submit', 1000)
- }
defineProps 和 defineEmits 都是只能在 中使用的编译器宏。他们不需要导入,且会随着 的处理过程一同被编译掉。
defineProps 接收与 props 选项相同的值,defineEmits 接收与 emits 选项相同的值。
defineProps 和 defineEmits 在选项传入后,会提供恰当的类型推导。
传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。
defineExpose使用 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 中声明的绑定。
可以通过 defineExpose 编译器宏来显式指定在 组件中要暴露出去的属性,若不使用defineExpose 则获取不到当前引用的组件实例变量、方法
- import { ref,defineExpose } from 'vue'
-
- const a = 1
- const b = ref(2)
-
- defineExpose({
- a,
- b
- })
下面通过父组件获取子组件实例时 加definedExpose和不加 definedExpose的区别

useSlots() 和 useAttrs()useSlots 顾名思义 使用插槽的意思 那必然和插槽脱离不了关系
子组件 定义出一个插槽
- <div>
- <slot name="header"> slot>
- div>
-
- <script setup>
- import { onMounted, useSlots } from 'vue'
- onMounted(() => {
- const slot = useSlots()
- const slotHeader = slot.header()
- console.log(slot, slotHeader)
- })
- script>
父组件
- <ComSlot>
- <template v-slot:header>我是父组件使用了headertemplate>
- ComSlot>
来看打印出来的slot和slotHeader
useSlots是一个函数可以打印出组件中所有的插槽 而打印出来的插槽同样是函数 调用后可以看到插槽的基础信息

useAttrs
父组件
- <ComSlot class="box">
- <template v-slot:header><p>我是父组件使用了headerp>template>
- ComSlot>
子组件
- import { useAttrs } from 'vue'
- onMounted(() => {
- const artts = useAttrs()
- console.log(artts)
- })

useAttrs 可以拿到父组件传递过来的所有属性
一起使用 可以和普通的 一起使用。普通的 在有这些需要的情况下或许会被使用到:
中声明的选项,例如 inheritAttrs 或插件的自定义选项。- // 普通
-
- <script setup>
- // 在 setup() 作用域中执行 (对每个实例皆如此)
- script>
await 中可以使用顶层 await。结果代码会被编译成 async setup():
- const post = await fetch('https://api.uomg.com/api/rand.qinghua').then((r) => r.json())
另外,await 的表达式会自动编译成在 await 之后保留当前组件实例上下文的格式。

注意:async setup() 必须与 Suspense 内置组件组合使用,Suspense 目前还是处于实验阶段的特性,会在将来的版本中稳定。
使用await demo
父组件
-
- <div>
- <Suspense>
- <template v-slot:default> <ComAwait>ComAwait> template>
- <template v-slot:fallback> <div>加载中div> template>
- Suspense>
- div>
-
- <script setup>
- import { defineAsyncComponent } from 'vue' // 使用defineAsyncComponent异步引入组件
- const ComAwait = defineAsyncComponent(() =>
- import('@/components/ComAwait.vue')
- )
- script>
子组件
- <div>{{post.content}}div>
-
- <script setup>
- const post = await fetch('https://api.uomg.com/api/rand.qinghua').then((r) => r.json())
- script>