<script setup>
是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。相比于普通的 <script>
语法,它具有更多优势:
- 更少的样板内容,更简洁的代码。
- 能够使用纯 Typescript 声明 props 和抛出事件。
- 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
- 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)。
#基本语法
要使用这个语法,需要将 setup
attribute 添加到 <script>
代码块上:
<script setup>
console.log('hello script setup')
</script>
里面的代码会被编译成组件 setup()
函数的内容。这意味着与普通的 <script>
只在组件被首次引入的时候执行一次不同,<script setup>
中的代码会在每次组件实例被创建的时候执行。
#defineProps
和 #defineEmits
在 <script setup>
中必须使用 defineProps
和 defineEmits
API 来声明 props
和 emits
,它们具备完整的类型推断并且在 <script setup>
中是直接可用的:
父组件:parent.vue
<template>
<div class="">
<h1>vue3语法糖</h1>
<child :count="count" @changeCount="changeCount"></child>
</div>
</template>
<script setup>
import { ref } from "vue";
// 引入子组件
import child from "../../components/child"
const count = ref(0);
const changeCount = () => {
count.value++
}
</script>
子组件:child.vue
<template>
<div>
<p>子组件:{{count}}</p>
<el-button type="primary" @click="changeCount">修改子组件</el-button>
</div>
</template>
<script setup>
import { ref } from "vue";
//defineProps使用方法
defineProps({
count: {
type: Number
}
});
//defineEmits使用方法
const emit = defineEmits(['changeCount'])
const changeCount = ()=>{
emit('changeCount')
}
</script>
defineProps
和 defineEmits
都是只在 <script setup>
中才能使用的编译器宏。他们不需要导入且会随着 <script setup>
处理过程一同被编译掉。
#defineExpose
父组件:parent.vue
<template>
<div class="">
<h1>vue3语法糖</h1>
<child ref="childComponent"></child>
<el-button type="primary" @click="getChild">获取子组件中暴露的值</el-button>
</div>
</template>
<script setup>
import { ref } from "vue";
// 引入子组件
import child from "../../components/child"
//注册ref,获取组件
const childComponent = ref();
const getChild = () =>{
//在组件的value属性中获取暴露的值
console.log(child.value.count,"获取子组件暴露的值")
}
</script>
子组件:child.vue
<template>
<div>
<p>子组件:{{count}}</p>
<el-button type="primary" @click="exposeCount">defineExpose</el-button>
</div>
</template>
<script setup>
import { ref } from "vue";
//暴露出子组件中的属性
const count = ref(0);
function exposeCount(){
count.value++
}
defineExpose({
count
})
</script>
#useSlots
和 #useAttrs
在 <script setup>
使用 slots
和 attrs
的情况应该是很罕见的,因为可以在模板中通过 $slots
和 $attrs
来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlots
和 useAttrs
两个辅助函数:
父组件:
<template>
<div class="">
<h1>vue3语法糖</h1>
<child dataId="123"></child>
</div>
</template>
<script setup>
// 引入子组件
import carrierCom from "../../components/carrierCom"
</script>
子组件:
<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
console.log(attrs.dataId,":查看父组件传来的自定义属性")
</script>