设计模式
<script setup>
在我们深入研究 `<script setup>` 语法及其含义之前,让我们快速回顾一下两个概念——**单文件组件**和**组合式 API**。
在 Vue 中,SFC 通过使我们能够在一个单独的 **`.vue`** 文件中定义组件的 HTML/CSS 和 JS 来帮助耦合逻辑。单文件组件由三个部分组成
<template>
<!-- HTML template goes here -->
</template>
<script>
// JavaScript logic goes here
</script>
<style>
/* CSS styles go here */
</style>
<template>
包含组件的纯 HTML 标记,<script>
导出包含该组件中所有 JS 逻辑的组件对象构造函数,以及 <style>
包含所有组件样式。
组合式 API 提供了代表 Vue 核心功能的独立函数。这些函数主要用在一个单独的 `setup()` 选项中,该选项充当使用组合式 API 的入口点。
<!-- Template -->
<script>
export default {
name: "MyComponent",
setup() {
// the setup function
},
};
</script>
<!-- Styles -->
请务必阅读 组合式 API 指南,以深入了解组合式 API 相对于传统选项式 API 语法的优势。
<script setup>
<script setup>
是编译时语法糖,允许在使用组合式 API 定义 Vue 选项时使用更简洁高效的语法。根据 Vue 文档,如果 同时使用 SFC 和组合式 API,则推荐使用这种语法。
通过使用 `<script setup>` 块,我们可以将组件逻辑压缩到一个单独的块中,从而无需显式定义 `setup()` 函数。要使用 `<script setup>` 语法,我们只需要在 `<script />` 块中引入 `setup` 属性。
<script setup>
// ...
</script>
让我们探索 `<script setup>` 提供的一些主要语法差异。
无返回语句
使用 `<script setup>` 语法,我们不再需要在块的末尾定义 `return` 语句。在顶层声明的绑定(函数、变量、导入等)可以直接访问和使用在模板中。
之前
<template>
<div>
<p>Count: {{ count }}</p>
<p>Username: {{ state.username }}</p>
<button @click="increment">Increment Count</button>
</div>
</template>
<script>
import { ref, reactive, onMounted } from "vue";
setup() {
const count = ref(0);
const state = reactive({username: "John"});
const increment = () => {
count.value++;
};
onMounted(() => {
console.log("Component mounted");
});
return {
count,
state,
increment
};
},
</script>
之后
<template>
<div>
<p>Count: {{ count }}</p>
<p>Username: {{ state.username }}</p>
<button @click="increment">Increment Count</button>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
const count = ref(0);
const state = reactive({ username: "John" });
const increment = () => {
count.value++;
};
onMounted(() => {
console.log("Component mounted");
});
</script>
无本地注册组件
组件导入会在 `<script setup>` 块中自动识别和解析,无需在 `components` 选项中显式声明组件。
之前
<template>
<ButtonComponent />
</template>
<script>
import ButtonComponent from "./components/ButtonComponent.vue";
export default {
setup() {
// the setup function
},
components: {
ButtonComponent,
},
};
</script>
之后
<template>
<ButtonComponent />
</template>
<script setup>
import { ButtonComponent } from "./components/Button";
</script>
defineProps()
通过使用 `defineProps()` 函数,可以在 `<script setup>` 块中直接访问 props。
之前
<template>
<button>{{ buttonText }}</button>
</template>
<script>
export default {
props: {
buttonText: String,
},
};
</script>
之后
<template>
<button>{{ buttonText }}</button>
</template>
<script setup>
const { buttonText } = defineProps({
buttonText: String,
});
</script>
defineProps()
还允许我们使用纯 TypeScript 声明 props 的形状。
<template>
<button>{{ buttonText }}</button>
</template>
<script setup lang="ts">
const { buttonText } = defineProps<{ buttonText: string }>();
</script>
为了在上述类型声明中提供默认的 prop 值,可以使用 `withDefaults()` 编译宏来实现。
<template>
<button>{{ buttonText }}</button>
</template>
<script setup lang="ts">
const { buttonText } = withDefaults(defineProps<{ buttonText: string }>(), {
buttonText: "Initial button text",
});
</script>
defineProps
仅在 `<script setup>` 中可用,无需导入即可使用。
defineEmits()
与 props 类似,自定义事件可以通过在组件中使用 `defineEmits()` 函数直接在 `<script setup>` 块中发出。
之前
<template>
<button @click="closeButton">Button Text</button>
</template>
<script>
export default {
emits: ["close"],
setup(props, { emit }) {
const closeButton = () => emit("close");
return {
closeButton,
};
},
};
</script>
之后
<template>
<button @click="closeButton">Button Text</button>
</template>
<script setup>
const emit = defineEmits(["close"]);
const closeButton = () => emit("close");
</script>
与 `defineProps` 一样,`defineEmits` 是一个特殊的关键字,仅在 `<script setup>` 中可用,并且无需导入即可使用。它还允许我们在 TypeScript 环境中直接传递类型。
<template>
<button @click="closeButton">Button Text</button>
</template>
<script setup lang="ts">
const emit = defineEmits<{ (e: "close"): void }>(["close"]);
const closeButton = () => emit("close");
</script>
<script setup>
与 setup()
对于具有大量返回选项和许多本地注册子组件的大型组件,`<script setup>` 语法有助于消除大量样板代码,从而导致更简洁、更专注的组件定义,这反过来有助于使代码库更易读、更易维护。
除了减少样板代码之外,`<script setup>` 语法还提供更好的运行时性能、更好的 IDE 类型推断性能以及使用 TypeScript 声明 props 和发射事件形状的能力。
有关使用 `<script setup>` 语法时需要注意的所有更改的完整列表,请参阅下面共享的官方 Vue 文档。