Vue 3 <script setup> 语法详解
Vue 3 <script setup>
语法详解
<script setup>
是 Vue 3 引入的一种编译时语法糖,它极大地改善了开发者在单文件组件(SFC)中的开发体验。下面我将详细解释它的特性和用法。
基本概念
<script setup>
是在单文件组件(SFC)中使用组合式 API 的更简洁语法。它让代码更简洁,减少了样板代码,同时提供了更好的类型推断支持。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue 3 script setup 示例</title><script src="https://unpkg.com/vue@3/dist/vue.global.js"></script><style>body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;background-color: #f5f7fa;color: #333;}.container {background: white;border-radius: 10px;padding: 20px;box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);}h1 {color: #42b883;border-bottom: 2px solid #42b883;padding-bottom: 10px;}h2 {color: #35495e;}.feature-block {background: #f9f9f9;border-left: 4px solid #42b883;padding: 15px;margin: 15px 0;border-radius: 0 5px 5px 0;}code {background: #272822;color: #f8f8f2;padding: 2px 6px;border-radius: 4px;font-family: 'Fira Code', monospace;}pre {background: #272822;color: #f8f8f2;padding: 15px;border-radius: 5px;overflow-x: auto;}.comparison {display: flex;gap: 20px;margin: 20px 0;}.comparison > div {flex: 1;background: #f9f9f9;padding: 15px;border-radius: 5px;}.btn {background: #42b883;color: white;border: none;padding: 10px 15px;border-radius: 4px;cursor: pointer;font-size: 16px;margin: 5px;transition: background 0.3s;}.btn:hover {background: #368a6a;}</style>
</head>
<body><div id="app"></div><script type="module">const { createApp } = Vue;// 子组件const ChildComponent = {template: `<div class="feature-block"><h3>子组件</h3><p>从父组件接收的消息: {{ message }}</p><button class="btn" @click="sendMessageToParent">向父组件发送消息</button></div>`,props: {message: String},emits: ['message-to-parent'],setup(props, { emit }) {function sendMessageToParent() {emit('message-to-parent', '来自子组件的问候!');}return {sendMessageToParent};}};const app = createApp({setup() {const message = Vue.ref('Hello Vue 3!');const count = Vue.ref(0);const childMessage = Vue.ref('');function increment() {count.value++;}function receiveMessage(msg) {childMessage.value = msg;}return {message,count,increment,childMessage,receiveMessage};},template: `<div class="container"><h1>Vue 3 <script setup> 语法详解</h1><div class="feature-block"><h2>基本响应式状态</h2><p>{{ message }}</p><button class="btn" @click="increment">计数: {{ count }}</button></div><div class="feature-block"><h2>组件通信</h2><p>来自子组件的消息: {{ childMessage }}</p><child-component :message="'来自父组件的消息 '" @message-to-parent="receiveMessage"></child-component></div><h2><script setup> 的优势</h2><div class="comparison"><div><h3>传统写法</h3><pre><code>
<script>
export default {setup() {const count = ref(0)const increment = () => count.value++return {count,increment}}
}
</script></code></pre></div><div><h3><script setup> 写法</h3><pre><code>
<script setup>
import { ref } from 'vue'const count = ref(0)
const increment = () => count.value++
</script></code></pre></div></div><div class="feature-block"><h2>主要特性</h2><ul><li>更简洁的代码 - 不需要从 setup() 函数返回变量和方法</li><li>更好的类型推断 - 对 TypeScript 支持更友好</li><li>更好的运行时性能 - 模板编译为没有代理的渲染函数</li><li>可以使用顶层 await - 使得异步代码更简洁</li></ul></div></div>`});app.component('ChildComponent', ChildComponent);app.mount('#app');</script>
</body>
</html>
核心特性解释
1. 自动暴露顶层绑定
在 <script setup>
中,所有顶层绑定(变量、函数、import导入)自动可用于模板,无需return语句。
2. 组件使用
直接import组件后即可在模板中使用,无需在components选项中注册。
3. 定义props和emits
使用defineProps和defineEmits编译器宏来声明props和emits:
<script setup>
const props = defineProps({title: String,count: Number
})const emit = defineEmits(['update', 'delete'])
</script>
4. 使用Slots和Attrs
可以通过useSlots和useAttrs来访问slots和attrs:
<script setup>
import { useSlots, useAttrs } from 'vue'const slots = useSlots()
const attrs = useAttrs()
</script>
5. 顶层await
在<script setup>
中可以直接使用顶层await:
<script setup>
const data = await fetch('/api/data').then(res => res.json())
</script>
与传统写法的对比
传统写法需要将所有的变量和方法从setup函数中返回,而<script setup>
自动完成这一过程,大大简化了代码结构。
总结
<script setup>
是Vue 3组合式API的重要补充,它提供了更简洁的语法、更好的类型推断支持,并且减少了样板代码。对于新项目,强烈推荐使用<script setup>
语法。
以上示例展示了<script setup>
的主要特性,可以直接运行这段代码来查看效果。