mcpField
S
script-setup

script-setup

github.com/patternsdev开发257186 次安装28 周前更新
代码仓库

关于 script-setup

面向使用 Vue 3 单文件组件和 Composition API 的开发者,介绍 `<script setup>` 语法及其用法,涵盖模板绑定、属性、事件和 TypeScript 默认值。

主要功能

  1. 01顶层绑定自动用于模板
  2. 02使用 `defineProps()` 和 `defineEmits()`
  3. 03用 `withDefaults()` 设置 TypeScript 属性默认值
  4. 04导入组件后无需注册即可使用

适用场景

  1. 01减少 Vue 组件定义中的样板代码
  2. 02声明组件属性和事件
  3. 03在模板中直接使用导入的组件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/patternsdev/skills --skill script-setup

安装后在 Claude Code 中输入/script-setup确认已加载。

详细介绍

<script setup>

目录

<script setup> 是在 Vue 单文件组件中使用组合式 API 的编译时语法糖。它会自动将顶层绑定暴露给模板,无需显式编写 return 语句,从而减少样板代码。

适用场景

  • 在 Vue 3 中同时使用单文件组件和组合式 API 时,推荐使用此语法
  • 有助于减少组件定义中的样板代码

使用说明

  • 为 <script> 标签添加 setup 属性:<script setup>
  • 顶层绑定(变量、函数、导入项)会自动在模板中可用,无需 return
  • 使用 defineProps() 和 defineEmits()(无需导入)来处理 props 和事件
  • 使用 withDefaults() 为 TypeScript 中的 prop 设置默认值
  • 导入的组件会自动在模板中可用,无需显式注册

详情

在深入了解 <script setup> 语法及其用途之前,我们先快速回顾两个概念——单文件组件和组合式 API。

在 Vue 中,单文件组件(SFC)让我们能够在单个 .vue 文件中定义组件的 HTML、CSS 和 JS,从而将逻辑整合在一起。单文件组件由三个部分组成:

<template>
  
</template>

<script>
  // JavaScript logic goes here
</script>

<style>
  /* CSS styles go here */
</style>

<template> 包含以纯 HTML 编写的组件标记,<script> 导出组件对象构造器,其中包含该组件的所有 JS 逻辑,而 <style> 则包含组件的所有样式。

组合式 API 提供了表示 Vue 核心功能的独立函数。这些函数主要在单个 setup() 选项中使用,它是使用组合式 API 的入口。



<script>
  export default {
    name: "MyComponent",
    setup() {
      // the setup function
    },
  };
</script>


请务必阅读 组合式函数指南,深入了解组合式 API 相较于传统选项式 API 语法的优势。

<script setup>

<script setup> 是一种编译时语法糖,可让我们以更简洁、高效的语法通过组合式 API 定义 Vue 选项。根据 Vue 文档,如果同时使用单文件组件和组合式 API,推荐使用此语法。

使用 <script setup> 代码块,我们可以将组件逻辑精简到一个代码块中,无需显式定义 setup() 函数。要使用 <script setup> 语法,只需为 <script /> 代码块添加 setup 属性。

<script setup>
  // ...
</script>

下面来看看 <script setup> 带来的一些主要语法差异。

无需 return 语句

使用 <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 官方文档。

来源

参考资料

评论

支持 Markdown