网页
综合
更新时间 2026-11-13 16:59:47
<script setup> | Vue.js
自动蜘蛛
vuejs.org
正文约 5999 字
Reactivity: Utilities
Reactivity: Advanced
Dependency Injection
Options: Composition
Syntax Specification
Server-Side Rendering
TypeScript Utility Types
<script setup> is a compile-time syntactic sugar for using Composition API inside Single-File Components (SFCs). It is the recommended syntax if you are using both SFCs and Composition API. It provides a number of advantages over the normal <script> syntax:
To opt-in to the syntax, add the setup attribute to the <script> block:
The code inside is compiled as the content of the component's setup() function. This means that unlike normal <script>, which only executes once when the component is first imported, code inside <script setup> will execute every time an instance of the component is created.
When using <script setup>, any top-level bindings (including variables, function declarations, and imports) declared inside <script setup> are directly usable in the template:
Imports are exposed in the same fashion. This means you can directly use an imported helper function in template expressions without having to expose it via the methods option:
Reactive state needs to be explicitly created using Reactivity APIs. Similar to values returned from a setup() function, refs are automatically unwrapped when referenced in templates:
Values in the scope of <script setup> can also be used directly as custom component tag names:
Think of MyComponent as being referenced as a variable. If you have used JSX, the mental model is similar here. The kebab-case equivalent <my-component> also works in the template - however PascalCase component tags are strongly recommended for consistency. It also helps differentiating from native custom elements.
Since components are referenced as variables instead of registered under string keys, we should use dynamic :is binding when using dynamic components inside <script setup>:
Note how the components can be used as variables in a ternary expression.
An SFC can implicitly refer to itself via its filename. E.g. a file named FooBar.vue can refer to itself as <FooBar/> in its template.
Note this has lower priority than imported components. If you have a named import that conflicts with the component's inferred name, you can alias the import:
You can use component tags with dots like <Foo.Bar> to refer to components nested under object properties. This is useful when you import multiple components from a single file:
Globally registered custom directives just work as normal. Local custom directives don't need to be explicitly registered with <script setup>, but they must follow the naming scheme vNameOfDirective:
If you're importing a directive from elsewhere, it can be renamed to fit the required naming scheme:
To declare options like props and emits with full type inference support, we can use the defineProps and defineEmits APIs, which are automatically available inside <script setup>:
defineProps and defineEmits are compiler macros only usable inside <script setup>. They do not need to be imported, and are compiled away when <script setup> is processed.
defineProps accepts the same value as the props option, while defineEmits accepts the same value as the emits option.
defineProps and defineEmits provide proper type inference based on the options passed.
The options passed to defineProps and defineEmits will be hoisted out of setup into module scope. Therefore, the options cannot reference local variables declared in setup scope. Doing so will result in a compile error. However, it can reference imported bindings since they are in the module scope as well.
Props and emits can also be declared using pure-type syntax by passing a literal type argument to defineProps or defineEmits:
defineProps or defineEmits can only use either runtime declaration OR type declaration. Using both at the same time will result in a compile error.
When using type declaration, the equivalent runtime declaration is automatically generated from static analysis to remove the need for double declaration and still ensure correct runtime behavior.
In dev mode, the compiler will try to infer corresponding runtime validation from the types. For example here foo: String is inferred from the foo: string type. Imported types are also resolved, provided TypeScript is installed as a peer dependency.
In prod mode, the compiler will generate the array format declaration to reduce bundle size (the props here will be compiled into ['foo', 'bar'])
In version 3.2 and below, the generic type parameter for defineProps() were limited to a type literal or a reference to a local interface.
This limitation was resolved in 3.3. The latest version of Vue supports referencing imported and a limited set of complex types in the type parameter position. However, because the type to runtime conversion is still AST-based, some complex types that require actual type analysis, e.g. conditional types, are not supported. You can use conditional types for the type of a single prop, but not the entire props object.
In Vue 3.5 and above, variables destructured from the return value of defineProps are reactive. Vue's compiler automatically prepends props. when code in the same <script setup> block accesses variables destructured from defineProps:
The above is compiled to the following equivalent:
In addition, you can use JavaScript's native default value syntax to declare default values for the props. This is particularly useful when using the type-based props declaration:
In 3.5 and above, default values can be naturally declared when using Reactive Props Destructure. But in 3.4 and below, Reactive Props Destructure is not enabled by default. In order to declare props default values with type-based declaration, the withDefaults compiler macro is needed:
This will be compiled to equivalent runtime props default options. In addition, the withDefaults helper provides type checks for the default values, and ensures the returned props type has the optional flags removed for properties
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。