---
url: /api/sfc-script-setup.md
---
# \
```
The code inside is compiled as the content of the component's `setup()` function. This means that unlike normal `
```
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:
```vue
{{ capitalize('hello') }}
```
## Reactivity {#reactivity}
Reactive state needs to be explicitly created using [Reactivity APIs](./reactivity-core). Similar to values returned from a `setup()` function, refs are automatically unwrapped when referenced in templates:
```vue
```
## Using Components {#using-components}
Values in the scope of `
```
Think of `MyComponent` as being referenced as a variable. If you have used JSX, the mental model is similar here. The kebab-case equivalent `` also works in the template - however PascalCase component tags are strongly recommended for consistency. It also helps differentiating from native custom elements.
### Dynamic Components {#dynamic-components}
Since components are referenced as variables instead of registered under string keys, we should use dynamic `:is` binding when using dynamic components inside `
```
Note how the components can be used as variables in a ternary expression.
### Recursive Components {#recursive-components}
An SFC can implicitly refer to itself via its filename. E.g. a file named `FooBar.vue` can refer to itself as `` 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:
```js
import { FooBar as FooBarChild } from './components'
```
### Namespaced Components {#namespaced-components}
You can use component tags with dots like `` to refer to components nested under object properties. This is useful when you import multiple components from a single file:
```vue
label
```
## Using Custom Directives {#using-custom-directives}
Globally registered custom directives just work as normal. Local custom directives don't need to be explicitly registered with `
This is a Heading
```
If you're importing a directive from elsewhere, it can be renamed to fit the required naming scheme:
```vue
```
## defineProps() & defineEmits() {#defineprops-defineemits}
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 `
```
- `defineProps` and `defineEmits` are **compiler macros** only usable inside `
```
```vue [Parent.vue]
```
:::
### Modifiers and Transformers {#modifiers-and-transformers}
To access modifiers used with the `v-model` directive, we can destructure the return value of `defineModel()` like this:
```js
const [modelValue, modelModifiers] = defineModel()
// corresponds to v-model.trim
if (modelModifiers.trim) {
// ...
}
```
When a modifier is present, we likely need to transform the value when reading or syncing it back to the parent. We can achieve this by using the `get` and `set` transformer options:
```js
const [modelValue, modelModifiers] = defineModel({
// get() omitted as it is not needed here
set(value) {
// if the .trim modifier is used, return trimmed value
if (modelModifiers.trim) {
return value.trim()
}
// otherwise, return the value as-is
return value
}
})
```
### Usage with TypeScript {#usage-with-typescript}
Like `defineProps` and `defineEmits`, `defineModel` can also receive type arguments to specify the types of the model value and the modifiers:
```ts
const modelValue = defineModel()
// ^? Ref
// default model with options, required removes possible undefined values
const modelValue = defineModel({ required: true })
// ^? Ref
const [modelValue, modifiers] = defineModel()
// ^? Record<'trim' | 'uppercase', true | undefined>
```
## defineExpose() {#defineexpose}
Components using `
```
When a parent gets an instance of this component via template refs, the retrieved instance will be of the shape `{ a: number, b: number }` (refs are automatically unwrapped just like on normal instances).
## defineOptions() {#defineoptions}
- Only supported in 3.3+
This macro can be used to declare component options directly inside `
```
- This is a macro. The options will be hoisted to module scope and cannot access local variables in `
```
## `useSlots()` & `useAttrs()` {#useslots-useattrs}
Usage of `slots` and `attrs` inside `
```
`useSlots` and `useAttrs` are actual runtime functions that return the equivalent of `setupContext.slots` and `setupContext.attrs`. They can be used in normal composition API functions as well.
## Usage alongside normal `
```
Support for combining `
```
In addition, the awaited expression will be automatically compiled in a format that preserves the current component instance context after the `await`.
:::warning Note
`async setup()` must be used in combination with [`Suspense`](/guide/built-ins/suspense.html), which is currently still an experimental feature. We plan to finalize and document it in a future release - but if you are curious now, you can refer to its [tests](https://github.com/vuejs/core/blob/main/packages/runtime-core/__tests__/components/Suspense.spec.ts) to see how it works.
:::
## Import Statements {#imports-statements}
Import statements in vue follow [ECMAScript module specification](https://nodejs.org/api/esm.html).
In addition, you can use aliases defined in your build tool configuration:
```vue
```
## Generics {#generics}
Generic type parameters can be declared using the `generic` attribute on the `
```
The value of `generic` works exactly the same as the parameter list between `<...>` in TypeScript. For example, you can use multiple parameters, `extends` constraints, default types, and reference imported types:
```vue
```
You can use `@vue-generic` the directive to pass in explicit types, for when the type cannot be inferred:
```vue
```
In order to use a reference to a generic component in a `ref` you need to use the [`vue-component-type-helpers`](https://www.npmjs.com/package/vue-component-type-helpers) library as `InstanceType` won't work.
```vue
```
```vue
```
[Read documentation on skip link to main content](https://www.w3.org/WAI/WCAG21/Techniques/general/G1.html)
## Content Structure {#content-structure}
One of the most important pieces of accessibility is making sure that design can support accessible implementation. Design should consider not only color contrast, font selection, text sizing, and language, but also how the content is structured in the application.
### Headings {#headings}
Users can navigate an application through headings. Having descriptive headings for every section of your application makes it easier for users to predict the content of each section. When it comes to headings, there are a couple of recommended accessibility practices:
- Nest headings in their ranking order: `
` - `
`
- Don’t skip headings within a section
- Use actual heading tags instead of styling text to give the visual appearance of headings
[Read more about headings](https://www.w3.org/TR/UNDERSTANDING-WCAG20/navigation-mechanisms-descriptive.html)
```vue-html
Main title
Section Title
Section Subtitle
Section Title
Section Subtitle
Section Subtitle
```
### Landmarks {#landmarks}
[Landmarks](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/landmark_role) provide programmatic access to sections within an application. Users who rely on assistive technology can navigate to each section of the application and skip over content. You can use [ARIA roles](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles) to help you achieve this.
| HTML | ARIA Role | Landmark Purpose |
| --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------- |
| header | role="banner" | Prime heading: title of the page |
| nav | role="navigation" | Collection of links suitable for use when navigating the document or related documents |
| main | role="main" | The main or central content of the document. |
| footer | role="contentinfo" | Information about the parent document: footnotes/copyrights/links to privacy statement |
| aside | role="complementary" | Supports the main content, yet is separated and meaningful on its own content |
| search | role="search" | This section contains the search functionality for the application |
| form | role="form" | Collection of form-associated elements |
| section | role="region" | Content that is relevant and that users will likely want to navigate to. Label must be provided for this element |
[Read more about landmarks](https://www.w3.org/TR/wai-aria-1.2/#landmark_roles)
## Semantic Forms {#semantic-forms}
When creating a form, you can use the following elements: `