setup选项
新的setup选项在组件创建之前执行,一旦props被解析,就将作为组合式API的入口。
在
setup中你应该避免使用this,因为它不会找到组件实例。setup的调用发生在dataproperty、computedproperty或methods被解析之前,所有它们无法在setup中被获取。setup选项是一个接收props和context函数,此外,我们将setup返回的所有内容都暴露给组件的其余部分(计算属性、方法、生命周期钩子等等)以及组件的模板。
<script setup>语法糖
<script setup>是在单文件组件SFC中使用组合式API的语法糖。相比于普通的<script>语法,它具有更多优势:
- 更少的样板内容,更简洁的代码。
- 能够使用纯TypeScript声明props和抛出事件。
- 更好的运行时性能(其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)
- 更好的IDE类型推断性能(减少语言服务器从代码中抽离类型的工作)。
1.基本用法
要使用这个语法,需要将setup属性添加到<script>代码块上:
<script setup>
console.log('Hello script setup')
</script>
上面的代码会被编译成组件setup()函数的内容。这意味与普通的<script>只在组件被首次引入的时候执行一次不同,<script setup>中的代码会在 每次组件实例被创建的时候执行。
当使用<script setup>的时候,任何在<script setup>声明的顶层的绑定(包括变量、函数声明、以及import引入的内容)无需return都能在模板中直接使用:
<template>
<div @click="log">{{msg}}</div>
<button @click="count++">{{count}}</button>
<!-- 使用组件 -->
<Child />
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
// 变量
const msg = 'hello!'
// 函数
function log () {
console.log(msg)
}
// 响应式
const count = ref(0)
</script>
2.defineProps和defineEmits
在<script setup>中必须使用defineProps和defineEmitsAPI来声明props和emits,它们具备完整的类型推断并且在<script setup>是直接可用的:
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
msg: String
})
const emits = defineEmits(['change', 'delete'])
</script>
defineProps和defineEmits都是只在<script setup>中才能使用的 编译器宏;defineProps接收与props选项相同的值,defineEmits接收与emits选项相同的值;defineProps和defineEmits在选项传入后,会提供恰当的类型推断;- 传入到
defineProps和defineEmits的选项会从setup中提升到模块的范围。
3.父子组件传值
- Father.vue父组件
<template>
<div>
我是父组件
<Child :msg="msg" @change-msg="handleChange" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './Child.vue'
const msg = ref('abcdef')
const handleChange = () => {
msg.value = 'aaaaaa'
}
</script>
- Child.vue子组件
<template>
<div>
<p>我是子组件,msg: {{props.msg}}</p>
<button @click="changeMsg">修改msg</button>
</div>
</template>
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
msg: String
})
const emits = defineEmits(['changeMsg'])
const changeMsg = () => {
emits('changeMsg', params)
}
</script>
4.useSlots和useAttrs
在<script setup>使用slots和attrs的情况应该是很罕见的,因为可以在模板中通过$slots和$attrs来访问它们。如果要使用,可以分别用useSlots和useAttrs两个辅助函数:
<template>
<div>
<p>msg: {{attrs.msg}}</p>
</div>
</template>
<script setup lang="ts">
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>