什么是script setup语法糖
<script setup> 是 Vue 3 中新增的语法糖,旨在简化组件中的逻辑代码。使用<script setup> 标签,可以在组件中通过 defineProps、defineEmits 和 defineExpose 等函数声明组件的属性、事件和暴露出去的 API,然后直接在组件模板中使用它们,而无需在 setup() 函数中再次声明。
此外,<script setup> 还支持通过 ref 和 reactive 等函数声明响应式数据,同时在 <template> 中直接使用。
使用<script setup>可以简化代码,并且能够提高开发效率,降低出错率,是 Vue 3 中非常值得推荐的特性。
用通俗易懂的话来说就是:
它简化了在单文件组件中编写组件选项的方式。在 <script setup> 中,可以使用类似于 setup() 函数的方式来定义组件的 props、响应式数据、计算属性、方法、事件等选项。
相比于传统的 <script lang="ts">setup(){}<script>,<script setup> 的优点有:
<script setup>,可以在同一个区块中定义组件的选项,减少了冗余的代码,提高了代码的可读性和维护性。<script setup> 中定义的变量类型可以被自动推导,减少了代码的冗余性和可读性。<script setup> 中定义的变量会被自动标记为只读的,这意味着 Vue 可以更好地优化渲染性能。总之,<script setup> 使得编写组件选项变得更加简洁、易读、易维护,并且能够提高渲染性能。
使用<script setup>语法糖编写组件的代码更为简洁和易读,相比之下,不使用语法糖则需要更多的代码来完成相同的功能。
下面是一个使用<script setup>的组件示例,它是一个简单的计数器:
<template>
<div>
<p>当前计数为:{{ count }}</p>
<button @click="incrementCount">增加计数</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
function incrementCount() {
count.value++
}
</script>
相比之下,下面是不使用语法糖的同一个组件的代码:
phpCopy code<template>
<div>
<p>当前计数为:{{ count }}</p>
<button @click="incrementCount">增加计数</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
function incrementCount() {
count.value++
}
return {
count,
incrementCount,
}
},
}
</script>
可以看到,使用<script setup>语法糖可以更清晰地表达组件的代码逻辑,同时也能更快地编写代码。
你还记得前面提到的语法糖的定义吗?
使用<script setup> 标签,可以在组件中通过 defineProps、defineEmits 和 defineExpose 等函数声明组件的属性、事件和暴露出去的 API,然后直接在组件模板中使用它们,而无需在 setup() 函数中再次声明。
如果记得,那么一定请记住无需显示export default导出 画蛇添足,因为不需要也不允许明令禁止!
举个例子,在<script setup>语法糖中将属性暴露出去给父组件传递属性props,我们只需要如下这样做
<template>
<footer>
<div class="center">
<span>Copyright ©{{ startYear }}-{{ currentYear }} {{ author }} </span>
<span v-if="icpNumber" class="icp-number">
<a href="http://beian.miit.gov.cn" target="_blank">{{ icpNumber }}</a>
</span>
</div>
</footer>
</template>
<script lang="ts" setup>
import { defineProps } from "vue";
interface PageFooterProps {
startYear: number;
author: string;
icpNumber?: string;
}
const props = defineProps<PageFooterProps>();
const currentYear = new Date().getFullYear();
</script>
<style lang="less" scoped>
footer {
// height: 10%;
background-color: #f3f4f5;
display: flex;
justify-content: center;
align-items: center;
.center {
text-align: center;
color: #4e77ab;
a {
text-decoration: none;
color: #4979ff;
}
}
}
</style>
也就是const props = defineProps<PageFooterProps>();,不需要再在前面加上exportdefault了,这不合法、也不允许!
1、由于在执行 setup函数的时候,还没有执行 Created 生命周期方法,所以在 setup 函数中,无法使用 data 和 methods 的变量和方法
2、由于我们不能在 setup函数中使用 data 和 methods,所以 Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了undefined
3、setup函数只能是同步的不能是异步的
<script setup>语法糖小结<script setup>
// 这里可以直接使用组合式 API,不需要绑定到 setup()
import { ref } from 'vue'
let message = ref('Hello!')
</script>
<template>
{{ message }}
</template>
<script setup> 中暴露变量和方法给其他组件使用<!-- ComponentA.vue -->
<script setup>
import { defineExpose } from 'vue'
const add = (a, b) => a + b
defineExpose({ add })
</script>
<!-- ComponentB.vue -->
import ComponentA from './ComponentA.vue'
const { add } = ComponentA
add(1, 2) // 3
</script>
用于在 <script setup> 中定义自定义事件
<!-- ComponentA.vue -->
<script setup>
import { defineEmit } from 'vue'
const emit = defineEmit(['add'])
function onAdd() {
emit('add')
}
</script>
ComponentB.vue:
<!-- ComponentB.vue -->
<script setup>
import ComponentA from './ComponentA.vue'
const instance = ComponentA()
instance.$on('add', () => {
console.log('add event fired')
})
</script>