ESLint Integration
## Installation
::: code-group
```bash [pnpm]
pnpm add -D @vue-macros/eslint-config
```
```bash [yarn]
yarn add -D @vue-macros/eslint-config
```
```bash [npm]
npm i -D @vue-macros/eslint-config
```
:::
## Configuration
### Flat Configuration
```js [eslint.config.js]
import vueMacros from '@vue-macros/eslint-config/flat'
export default [
vueMacros,
// ...your other configurations
]
```
### Legacy Configuration
```jsonc [.eslintrc]
{
"extends": [
"@vue-macros/eslint-config",
// ...your other configurations
],
}
```
---
---
url: /guide/nuxt-integration.md
---
# Nuxt Integration
### Installation
::: code-group
```bash [npm]
npm i -D @vue-macros/nuxt
```
```bash [yarn]
yarn add -D @vue-macros/nuxt
```
```bash [pnpm]
pnpm add -D @vue-macros/nuxt
```
:::
## Configuration
```ts [nuxt.config.ts]
export default {
modules: [
'@vue-macros/nuxt',
// ...
],
macros: {
// overrides config options
},
}
```
---
:tada: Congratulations! That's all.
To learn more about the macros, please visit [All Macros](/macros/) :laughing:.
---
---
url: /guide/astro-integration.md
---
# Astro Integration
### Installation
::: code-group
```bash [npm]
npm i -D @vue-macros/astro
```
```bash [yarn]
yarn add -D @vue-macros/astro
```
```bash [pnpm]
pnpm add -D @vue-macros/astro
```
:::
## Configuration
```ts [astro.config.mjs]
import Vue from '@astrojs/vue'
import Macros from '@vue-macros/astro'
import { defineConfig } from 'astro/config'
export default defineConfig({
integrations: [
Vue(),
Macros({
// overrides config options
}),
],
})
```
## TypeScript Support & Volar Support
See the corresponding chapter on [Bundler Integration](./bundler-integration.md#typescript-support)
---
:tada: Congratulations! That's all.
To learn more about the macros, please visit [All Macros](/macros/) :laughing:.
---
---
url: /features/better-define.md
---
# betterDefine
With enabling `betterDefine`, imported types are supported in `
```
<<< ./better-define.md#basic{ts} [types.ts]
:::
## ⚠️ Limitations
### Complex types
Complex types are not supported in some key places. For example:
#### What are Complex Types?
- All utility types
- [Built-in types](https://www.typescriptlang.org/docs/handbook/utility-types.html)
- All types from `type-fest` package.
- `typeof` keyword.
- ...
- Index Signature
```ts
interface Type {
[key: string]: string
}
```
- Generics will be ignored directly
#### What are Key Places?
- The names of props.
```ts
// ✅
defineProps<{
foo: ComplexType
}>()
// ❌
defineProps<{
[ComplexType]: string
}>()
```
- The names of emits.
```ts
interface Emits {
(event: 'something', value: ComplexType): void // ✅
(event: ComplexType): void // ❌
}
```
---
---
url: /features/boolean-prop.md
---
# booleanProp
Convert `` to ``.
Convert `` to ``.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :x: |
| Volar Plugin | :white_check_mark: |
## Options
```ts
interface Options {
/**
* @default '!'
*/
negativePrefix?: string
}
```
## Usage
```vue twoslash
// ^?
```
```vue twoslash
```
## Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"booleanProp": true,
},
},
}
```
---
---
url: /guide/bundler-integration.md
---
# Bundler Integration
## Installation
::: tip
Vite and Rollup are fully supported, while other bundlers have limited support.
:::
::: code-group
```bash [npm]
npm i -D vue-macros
```
```bash [yarn]
yarn add -D vue-macros
```
```bash [pnpm]
pnpm add -D vue-macros
```
:::
::: code-group
```ts [Vite]
// vite.config.ts
import Vue from '@vitejs/plugin-vue'
import VueMacros from 'vue-macros/vite'
// import VueJsx from '@vitejs/plugin-vue-jsx'
// import VueRouter from 'unplugin-vue-router/vite'
export default defineConfig({
plugins: [
VueMacros({
plugins: {
vue: Vue(),
// vueJsx: VueJsx(), // if needed
// vueRouter: VueRouter({ // if needed
// extensions: ['.vue', '.setup.tsx']
// })
},
// overrides plugin options
}),
],
})
```
```ts [Rollup]
// rollup.config.js (Requires Rollup 3+)
import Vue from 'unplugin-vue/rollup'
import VueMacros from 'vue-macros/rollup'
// import VueRouter from 'unplugin-vue-router/rollup'
export default {
plugins: [
VueMacros({
plugins: {
vue: Vue(),
// vueJsx: VueJsx(), // if needed
// vueRouter: VueRouter({ // if needed
// extensions: ['.vue', '.setup.tsx']
// })
},
// overrides plugin options
}),
],
}
```
```js [esbuild]
// esbuild.config.js
import { build } from 'esbuild'
// import VueRouter from 'unplugin-vue-router/esbuild'
build({
plugins: [
require('vue-macros/esbuild')({
plugins: {
vue: require('unplugin-vue/esbuild')(),
// vueJsx: VueJsx(), // if needed
// vueRouter: VueRouter({ // if needed
// extensions: ['.vue', '.setup.tsx']
// })
},
// overrides plugin options
}),
],
})
```
```js [Webpack]
// webpack.config.js (Requires Webpack 5+)
module.exports = {
/* ... */
plugins: [
require('vue-macros/webpack')({
// overrides plugin options
}),
],
}
```
```js [Rspack]
// rspack.config.js
module.exports = {
/* ... */
plugins: [
require('vue-macros/rspack')({
// overrides plugin options
}),
],
}
```
```js [Rsbuild]
// rsbuild.config.js
module.exports = {
// ...
tools: {
rspack: {
plugins: [
require('vue-macros/rspack')({
// overrides plugin options
}),
],
},
},
}
```
```js [Vue CLI]
// vue.config.js (Requires Vue CLI 5+)
const { defineConfig } = require('@vue/cli-service')
const VueMacros = require('vue-macros/webpack')
module.exports = defineConfig({
// ...
// ⚠️ IMPORTANT
parallel: false,
configureWebpack: {
plugins: [
VueMacros({
// overrides plugin options
}),
],
},
})
```
:::
## Configuration
See the [Configurations](./configurations.md) for more details.
```ts twoslash [vue-macros.config.ts]
import { defineConfig } from 'vue-macros'
export default defineConfig({
// options
})
```
## TypeScript Support
```json {0}
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["vue-macros/macros-global" /* ... */]
}
}
```
## Volar Support
For detailed configuration, please refer to the description of the specific macro.
```jsonc [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
### Scoped Plugins
`exportExpose`, `exportProps`, and `exportRender` plugins cannot be used
at the same time unless providing a scope.
```ts twoslash [vue-macros.config.ts]
import { defineConfig } from 'vue-macros'
export default defineConfig({
exportExpose: {
include: ['**/export-expose/**'],
},
exportProps: {
include: ['**/export-props/**'],
},
exportRender: {
include: ['**/export-render/**'],
},
})
```
---
:tada: Congratulations! You have successfully set up Vue Macros.
To learn more about the macros, please visit [All Macros](/macros/) :laughing:.
---
---
url: /macros/chain-call.md
---
# chainCall
Extends `defineProps`, support call `withDefaults` as a chain.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :question: |
| Vue 2 | :question: |
| TypeScript | :white_check_mark: |
| Volar Plugin | :x: |
::: tip
- `chainCall` does not support `definePropsRefs`
- To fully support TypeScript, you need to import this macro from `vue-macros/macros`.
:::
## Basic Usage
```vue
```
::: details Compiled Code
```vue twoslash
```
:::
Also support [props destructuring](../features/reactivity-transform.md) and JSX:
```vue
```
## TypeScript
To fully support TypeScript, you need to import this macro from `vue-macros/macros` with specific syntax.
```vue twoslash
```
Works without import assertion, but tsc will report an error:
```ts twoslash
// @errors: 2339
defineProps<{
/* ... */
}>().withDefaults({
/* ... */
})
```
---
---
url: /guide/configurations.md
---
# Configurations
## Plugin Options
All features are enabled by default except the following.
#### Disabled by Default
- `exportExpose`
- `exportProps`
- `exportRender`
- `setupSFC`
- `booleanProp`
- `shortBind`
- `defineStyleX`
#### Disabled by Default when Vue >= 3.3
- `defineOptions`
- `defineSlots`
- `hoistStatic`
- `shortEmits`
You can re-enable them by setting the option to `true`.
```ts twoslash [vue-macros.config.(ts,js,json)]
import { defineConfig } from 'vue-macros'
export default defineConfig({
root: '/your-project-path',
/**
* Vue version, 2 or 3.
*
* optional, detecting automatically.
*/
version: 3,
/** Defaults to true */
defineModels: {
// ...
},
// Enable features
defineOptions: true,
// Disable features
hoistStatic: false,
// ... more features
})
```
Refer to the macros and features page for available options.
---
---
url: /macros/define-emit.md
---
# defineEmit
Declare single emit one by one using `defineEmit`.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript | :white_check_mark: |
| Volar Plugin | :white_check_mark: |
::: warning
`defineEmit` can not be used with `defineEmits` at same time
:::
## API Reference
```ts
defineEmit(emitName)
defineEmit(emitName, validator)
// emitName parameter can be optional,
// and will be inferred from variable name
const emitName = defineEmit()
```
## Basic Usage
```vue twoslash
```
## With Validation
```vue twoslash
```
## TypeScript
```vue twoslash
```
## Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"defineEmit": true,
},
},
}
```
---
---
url: /volar/define-generic.md
---
# defineGeneric
Declare single generic one by one using `DefineGeneric`.
> Especially useful for `setup-sfc`.
| Features | Supported |
| :----------: | :----------------: |
| Volar Plugin | :white_check_mark: |
## Basic Usage
::: code-group
```vue [App.vue] twoslash
```
:::
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/define-models.md
---
# defineModels
Declaring and mutate `v-model` props as the same as normal variable using the `defineModels`.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| Volar Plugin | :white_check_mark: |
## Options
```ts
VueMacros({
defineModels: {
/**
* Unified mode, only works for Vue 2
*
* Converts `modelValue` to `value`
*/
unified: false,
},
})
```
## Basic Usage
Requires [`@vueuse/core`](https://www.npmjs.com/package/@vueuse/core), install it by yourself before using.
```vue twoslash
```
::: warning ❌ Object declaring is not supported.
```vue
```
:::
## With Model Options
```vue twoslash 3-6
```
## With Reactivity Transform
::: warning
Assignment expression is only supported in `
```
::: details Compiled Code
```vue twoslash
```
:::
## Volar Configuration
```jsonc {4,6-9} [tsconfig.json]
{
"vueCompilerOptions": {
"target": 3, // or 2.7 for Vue 2
"plugins": ["vue-macros/volar"],
"vueMacros": {
"defineModels": {
// Only works when target is 2.7.
"unified": true,
},
},
},
}
```
---
---
url: /macros/define-options.md
---
# defineOptions
Options API can be declared using the `defineOptions` in `
```
::: details Compiled Code
```vue twoslash
```
:::
## JSX in `
```
::: details Compiled Code
```vue
```
:::
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/define-prop.md
---
# defineProp
Declare single prop one by one using `defineProp`.
| Features | Supported |
| :----------------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript / Volar | :white_check_mark: |
::: warning
`defineProp` can not be used in the same file as type-declared `defineProps`.
:::
## Configuration
```ts
VueMacros({
defineProp: {
/**
* 'kevinEdition' | 'johnsonEdition'
* @default 'kevinEdition'
*/
edition: 'kevinEdition',
},
})
```
## Kevin's Edition (Default)
### API Reference
```ts
defineProp(propName)
defineProp(propName, options)
// propName parameter can be optional,
// and will be inferred from variable name
const propName = defineProp()
```
### Basic Usage
```vue twoslash
```
### With Options
```vue twoslash
```
### TypeScript
```vue twoslash
```
### With Reactivity Transform
```vue twoslash
```
## Johnson's Edition
### API Reference
```ts
// the prop name will be inferred from variable name
const propName = defineProp()
const propName = defineProp(defaultValue)
const propName = defineProp(defaultValue, required)
const propName = defineProp(defaultValue, required, rest)
```
### Basic Usage
```vue twoslash
```
### With Options
```vue twoslash
```
### TypeScript
```vue twoslash
```
### With Reactivity Transform
```vue twoslash
```
### Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"defineProp": true,
},
// "kevinEdition" | "johnsonEdition" | false
"experimentalDefinePropProposal": "kevinEdition",
},
}
```
---
---
url: /macros/define-props.md
---
# defineProps
Correct types of destructured props using `$defineProps`.
See also [Vue issue](https://github.com/vuejs/core/issues/6876), [Reactivity Transform RFC](https://github.com/vuejs/rfcs/blob/reactivity-transform/active-rfcs/0000-reactivity-transform.md#defineprops-destructure-details).
| Features | Supported |
| :-----------------------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript / Volar Plugin | :white_check_mark: |
::: warning
[Reactivity Transform](../features/reactivity-transform.md) is required. You should enable it first.
:::
## Basic Usage
```vue twoslash
```
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/define-props-refs.md
---
# definePropsRefs
Returns refs from `defineProps` instead of a reactive object. It can be destructured without losing reactivity.
`toRefs(defineProps())` => `definePropsRefs()`
| Features | Supported |
| :-----------------------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript / Volar Plugin | :white_check_mark: |
## Basic Usage
```vue twoslash {2-3,8}
```
## With Default Value
```vue twoslash {2-3,8}
```
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/define-render.md
---
# defineRender
Defining render function in `
```
---
---
url: /macros/define-slots.md
---
# defineSlots
Declaring type of SFC slots in `
```
### Full Syntax (Official Version)
```vue twoslash
```
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/define-stylex.md
---
# defineStyleX
Define and consume [StyleX](https://stylexjs.com/) styles in `
Red
```
:::details Compiled Code (with some simplifications)
```vue [App.vue] twoslash
Red
```
:::
## Conditional Styles
Optional and multiple rules are supported.
```vue [App.vue] twoslash
Red
```
:::details Compiled Code (with some simplifications)
```vue [App.vue] twoslash
Red
```
:::
---
---
url: /features/export-expose.md
---
# exportExpose
Transform export statement as `defineExpose` params in Vue SFC `script-setup`.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | ? |
| Vue 2 | :white_check_mark: |
| Volar Plugin | :white_check_mark: |
## Usage
Support these syntaxes:
- local variable/function/class
- export with alias
- export from other file
- namespace export
- rename export
### 1. local variable/function/class
```vue twoslash
```
::: details Compiled Code
```vue twoslash
```
:::
### 2. export with alias
```vue twoslash
```
::: details Compiled Code
```vue twoslash
```
:::
### 3. export from other file
::: code-group
```vue [App.vue] twoslash
```
<<< ./export-expose.md#export-file{ts} [types.ts]
:::
::: details Compiled Code
```vue twoslash
```
:::
### 4. namespace export
::: code-group
```vue [App.vue] twoslash
```
```ts [types.ts]
export const foo = 'foo'
```
:::
::: details Compiled Code
```vue twoslash
```
:::
### 5. rename export
```vue
```
::: details Compiled Code
```vue
```
:::
## Limitations
Currently does't support these following cases:
```ts
// 1. export all ❌
export * from '../types'
// 2. export default ❌
const a = 'a'
export default a
```
## Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"exportExpose": true,
},
},
}
```
---
---
url: /features/export-props.md
---
# exportProps
[Svelte-like Declaring props](https://svelte.dev/docs#component-format-script-1-export-creates-a-component-prop) for Vue.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :question: |
| Vue 2 | :white_check_mark: |
| Volar Plugin | :white_check_mark: |
## Pre-requisite
[Reactivity Transform](./reactivity-transform.md) is required to use this feature, but it is enabled by default in Vue Macros.
`export let` will be changed to `defineModel`, which is supported in Vue 3.4+.
## Usage
Using export syntax to declare props.
```vue twoslash
```
## Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"exportProps": true,
},
},
}
```
---
---
url: /features/export-render.md
---
# exportRender
Transform the default export statement, in `
```
## Volar Configuration
```jsonc {3,7} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"exportRender": true,
},
},
}
```
---
---
url: /guide/getting-started.md
---
# Getting Started
Vue Macros is a library that implements unofficial proposals and ideas for Vue,
exploring and extending its features and syntax.
We assume you are already familiar with the basic usages of Vue before you continue.
## Requirements
- Node.js `>= v20.18.0`.
- Vue `>= v2.7` or Vue `>= v3.0`.
- Some features need Vue `>= v3.2.25`.
- VSCode extension [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) and `vue-tsc` are v{{ version }}
- Vue Macros will continue to adapt to the latest version as soon as possible, older versions may not be supported.
::: warning
WebStorm is not supported.
:::
## Creating a Vue Macros Project
### Installation
::: code-group
```bash [npm]
npm i -g @vue-macros/cli
```
```bash [yarn]
yarn global add @vue-macros/cli
```
```bash [pnpm]
pnpm add -g @vue-macros/cli
```
:::
This command will install [@vue-macros/cli](https://github.com/vue-macros/vue-macros-cli), the official Vue Macros scaffolding tool.
### Initialization
::: code-group
```bash [npm]
npm create vite@latest my-vue-macros -- --template vue-ts
cd my-vue-macros
vue-macros init
```
```bash [yarn]
yarn create vite my-vue-macros --template vue-ts
cd my-vue-macros
vue-macros init
```
```bash [pnpm]
pnpm create vite my-vue-macros --template vue-ts
cd my-vue-macros
vue-macros init
```
You will be presented with prompts for several optional experimental features.
:::
## Templates
- [Vite](https://github.com/vue-macros/vite)
- [Nuxt](https://github.com/vue-macros/nuxt)
- [Rsbuild](https://github.com/vue-macros/vue3-rsbuild)
🌟 More templates are welcome!
## Nuxt Integration
If you're using [Nuxt](https://nuxt.com/), read the [Nuxt Integration](./nuxt-integration.md).
## Bundler Integrations
If you're using [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org/), [esbuild](https://esbuild.github.io/), [Webpack](https://webpack.js.org/), or [Rspack](https://www.rspack.dev/), read the [Bundler Integration](./bundler-integration.md).
---
---
url: /features/hoist-static.md
---
# hoistStatic
With enabling `hoistStatic`, constants declared in macros of `
```
::: details Compiled Code
```vue
```
:::
## Magic Comments
```vue
```
::: details Compiled Code
```vue
```
:::
---
---
url: /features/jsx-directive.md
---
# jsxDirective
Vue built-in directives for JSX.
| Directive | Vue 3 | Vue 2 | Volar |
| :---------: | :----------------: | :----------------: | :----------------: |
| `v-if` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `v-else-if` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `v-else` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `v-for` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `v-on` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `v-slot` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `v-html` | :white_check_mark: | :white_check_mark: | / |
| `v-once` | :white_check_mark: | :x: | / |
| `v-memo` | :white_check_mark: | :x: | / |
## Options
```ts
interface Options {
/**
* @default 'v-'
*/
prefix?: string
/**
* @default 'vue'
*/
lib?: 'vue' | 'react' | 'preact' | 'solid' | string
}
```
## Usage
### `v-if`, `v-else-if`, `v-else`
```vue twoslash
```
### `v-for`
```vue twoslash
```
### `v-slot`
::: code-group
```vue [App.vue] twoslash
```
<<< ./jsx-directive.md#v-slot{tsx} [Child.tsx]
:::
### `v-on`
::: warning
`v-on` only supports binding to an object of event / listener pairs without an argument.
:::
```tsx
```
## Dynamic Arguments
It is also possible to use a variable in a directive argument by wrapping it with a pair of `$`:
`v-model`
::: code-group
```vue [App.vue] twoslash
```
<<< ./jsx-directive.md#v-model{tsx} [Comp.tsx]
:::
`v-slot`
::: code-group
```vue [App.vue] twoslash
```
<<< ./jsx-directive.md#v-slot-dynamic{tsx} [Comp.tsx]
:::
## Modifiers
Modifiers are special postfixes denoted by a `_`, which indicate that a directive should be bound in some special way.
```tsx
```
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /volar/jsx-ref.md
---
# jsxRef
Automatically infer type for `useRef`.
| Features | Supported |
| :------: | :----------------: |
| Volar | :white_check_mark: |
## Setup Auto Import
::: code-group
```ts [vite.config.ts]
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
AutoImport({
imports: [
{
from: 'vue',
imports: [['shallowRef', 'useRef']],
},
],
}),
],
})
```
```ts [nuxt.config.ts]
export default defineNuxtConfig({
imports: {
presets: [
{
from: 'vue',
imports: [['shallowRef', 'useRef']],
},
],
},
})
```
:::
## Basic Usage
::: code-group
```vue [App.vue] twoslash
```
<<< ./jsx-ref.md#comp{ts} [Comp.ts]
:::
## Volar Configuration
```jsonc [tsconfig.json] {3,6}
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"jsxRef": {
"alias": ["useRef"],
},
},
},
}
```
---
---
url: /guide/migration-v3.md
---
# Migration from v2 to v3
## Unified Version Management
Initially, we used [`changesets`](https://github.com/changesets/changesets) to
manage the versions of all packages in the monorepo. However, after two years of experimentation,
we decided to adopt a single-version strategy in v3,
where all sub-packages share the same version number, similar to Vue and Babel.
This decision stemmed from our observation that when a sub-package underwent a major change or minor update,
the version number of the main package did not adequately reflect these changes.
For example, when `@vue-macros/define-prop` introduced a breaking change,
how should `unplugin-vue-macros` release a new version?
Should it be a minor or a patch release? When users updated `unplugin-vue-macros`,
they couldn’t easily determine whether the update was due to changes in `@vue-macros/define-prop`.
Therefore, after Anthony proposed [Epoch Semantic Versioning](https://antfu.me/posts/epoch-semver),
we decided to adopt a more frequent major version update strategy,
with all packages sharing the same version number and maintaining a single unified changelog.
## Main Package Rename
We have renamed the main package from `unplugin-vue-macros` to **`vue-macros`**.
After the official release of v3, `unplugin-vue-macros` will be marked as deprecated.
As a result, you will need to update your `package.json` and the import statements for Vue Macros:
```diff
// package.json
{
"devDependencies": {
- "unplugin-vue-macros": "^2.14.5"
+ "vue-macros": "^3.0.0"
}
}
```
```diff
- import { $ref } from 'unplugin-vue-macros/macros'
+ import { $ref } from 'vue-macros/macros'
- import VueMacros from 'unplugin-vue-macros/vite'
+ import VueMacros from 'vue-macros/vite'
```
## Dropping Vue 2 Support
Vue 2 reached its end of life (EOL) at the end of 2023, so we have decided to drop support for Vue 2 in v3.
If you are still using Vue 2, we recommend continuing with v2 or
considering our [paid support plan](https://github.com/vue-macros/vue-macros/issues/373).
## Node.js Compatibility Changes
In v3, we have dropped support for Node.js versions below 20.18.
This means the minimum Node.js version requirement for v3 is `20.18.0`.
Additionally, we have removed CommonJS (CJS) outputs and now only provide ECMAScript modules (ESM).
## Dropping Webpack 4 Support
Since Webpack 4 cannot run in Node.js 18 or later environments,
we have also dropped support for Webpack 4 and Vue CLI 4.
We recommend upgrading to modern build tools like Vite or Rspack.
---
---
url: /features/named-template.md
---
# namedTemplate
::: warning
Not actively maintained now. Try [createReusableTemplate](https://vueuse.org/core/createReusableTemplate/) instead.
:::
With enabling `namedTemplate`, `` can be referenced like a variable.
Sometimes we need to reverse the order of the very simple components, and don't want to give the features of Vue template up and use JSX/TSX. Then this feature is much helpful.
If you support this feature, you can go to [the discussion](https://github.com/vuejs/core/discussions/6898) and hit like :+1: or comment.
| Features | Supported |
| :----------------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Vue 3.3 | :x: |
| Nuxt 3 | :x: |
| Vue 2 | :x: |
| TypeScript / Volar | :x: |
## Basic Usage
```vue {5-7,10-12,16-18}
This is pagerHere is data table
```
## Known Usage
- TypeScript / Volar support is not yet completed.
---
---
url: /features/reactivity-transform.md
---
# Reactivity Transform
| Features | Supported |
| :----------------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript / Volar | :white_check_mark: |
## Installation Standalone Version
if you need Reactivity Transform feature only, the standalone version is more appropriate for you.
### Installation
::: code-group
```bash [npm]
npm i -D @vue-macros/reactivity-transform
```
```bash [yarn]
yarn add -D @vue-macros/reactivity-transform
```
```bash [pnpm]
pnpm add -D @vue-macros/reactivity-transform
```
:::
::: code-group
```ts [Vite]
// vite.config.ts
import ReactivityTransform from '@vue-macros/reactivity-transform/vite'
export default defineConfig({
plugins: [ReactivityTransform()],
})
```
```ts [Rollup]
// rollup.config.js
import ReactivityTransform from '@vue-macros/reactivity-transform/rollup'
export default {
plugins: [ReactivityTransform()],
}
```
```js [esbuild]
// esbuild.config.js
import { build } from 'esbuild'
build({
plugins: [require('@vue-macros/reactivity-transform/esbuild')()],
})
```
```js [Webpack]
// webpack.config.js
module.exports = {
/* ... */
plugins: [require('@vue-macros/reactivity-transform/webpack')()],
}
```
:::
### TypeScript Support
```json [tsconfig.json]
{
"compilerOptions": {
// ...
"types": ["@vue-macros/reactivity-transform/macros-global" /* ... */]
}
}
```
## Refs vs. Reactive Variables {#refs-vs-reactive-variables}
Ever since the introduction of the Composition API, one of the primary unresolved questions is the use of refs vs. reactive objects. It's easy to lose reactivity when destructuring reactive objects, while it can be cumbersome to use `.value` everywhere when using refs. Also, `.value` is easy to miss if not using a type system.
Reactivity Transform is a compile-time transform that allows us to write code like this:
```vue twoslash
```
The `$ref()` method here is a **compile-time macro**: it is not an actual method that will be called at runtime. Instead, the Vue compiler uses it as a hint to treat the resulting `count` variable as a **reactive variable.**
Reactive variables can be accessed and re-assigned just like normal variables, but these operations are compiled into refs with `.value`. For example, the `
```
The above will be compiled into the following runtime declaration equivalent:
```ts twoslash
import { defineComponent, watchEffect } from 'vue'
export default defineComponent({
props: {
msg: { type: String, required: true },
count: { type: Number, default: 1 },
foo: String,
},
setup(props) {
watchEffect(() => {
console.log(props.msg, props.count, props.foo)
})
},
})
```
## Retaining Reactivity Across Function Boundaries {#retaining-reactivity-across-function-boundaries}
While reactive variables relieve us from having to use `.value` everywhere, it creates an issue of "reactivity loss" when we pass reactive variables across function boundaries. This can happen in two cases:
### Passing into function as argument {#passing-into-function-as-argument}
Given a function that expects a ref as an argument, e.g.:
```ts twoslash
import { watch, type Ref } from 'vue'
function trackChange(x: Ref) {
watch(x, (x) => {
console.log('x changed!')
})
}
const count = $ref(0)
// @errors: 2345
trackChange(count) // doesn't work!
```
The above case will not work as expected because it compiles to:
```ts
const count = ref(0)
trackChange(count.value)
```
Here `count.value` is passed as a number, whereas `trackChange` expects an actual ref. This can be fixed by wrapping `count` with `$$()` before passing it:
```diff
let count = $ref(0)
- trackChange(count)
+ trackChange($$(count))
```
The above compiles to:
```js
import { ref } from 'vue'
const count = ref(0)
trackChange(count)
```
As we can see, `$$()` is a macro that serves as an **escape hint**: reactive variables inside `$$()` will not get `.value` appended.
### Returning inside function scope {#returning-inside-function-scope}
Reactivity can also be lost if reactive variables are used directly in a returned expression:
```ts twoslash
function useMouse() {
const x = $ref(0)
const y = $ref(0)
// listen to mousemove...
// doesn't work!
return {
x,
y,
}
}
```
The above return statement compiles to:
```ts
return {
x: x.value,
y: y.value,
}
```
In order to retain reactivity, we should be returning the actual refs, not the current value at return time.
Again, we can use `$$()` to fix this. In this case, `$$()` can be used directly on the returned object - any reference to reactive variables inside the `$$()` call will retain the reference to their underlying refs:
```ts twoslash
function useMouse() {
const x = $ref(0)
const y = $ref(0)
// listen to mousemove...
// fixed
return $$({
x,
y,
})
}
```
### Using `$$()` on destructured props {#using-on-destructured-props}
`$$()` works on destructured props since they are reactive variables as well. The compiler will convert it with `toRef` for efficiency:
```vue twoslash
```
compiles to:
```ts twoslash
import { defineComponent, toRef, type Ref } from 'vue'
function passAsRef(count: Ref) {
return count
}
// ---cut---
export default defineComponent({
props: {
count: { type: Number, required: true },
},
setup(props) {
const __props_count = toRef(props, 'count')
passAsRef(__props_count)
},
})
```
## TypeScript Integration {#typescript-integration}
Vue provides typings for these macros (available globally) and all types will work as expected. There are no incompatibilities with standard TypeScript semantics, so the syntax will work with all existing tooling.
This also means the macros can work in any files where valid JS / TS are allowed - not just inside Vue SFCs.
Since the macros are available globally, their types need to be explicitly referenced (e.g. in a `env.d.ts` file):
```ts [env.d.ts]
///
// or for standalone version:
///
```
When explicitly importing the macros from `vue-macros/macros` or `@vue-macros/reactivity-transform/macros-global`, the type will work without declaring the globals.
---
---
url: /features/script-lang.md
---
# scriptLang
Set the default language for `
```
## Volar Configuration
```jsonc {3,5-7} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"scriptLang": {
"defaultLang": "ts",
},
},
},
}
```
---
---
url: /volar/script-sfc.md
---
# scriptSFC
Enabled Volar support for `.ts` | `.tsx` files.
| Features | Supported |
| :----------: | :----------------: |
| Volar Plugin | :white_check_mark: |
## Basic Usage
### With `jsxDirective`
::: code-group
```tsx [App.tsx]
export default ({ foo }: { foo: number }) => (
{foo}
// ^ will be inferred as 1
)
```
:::
## Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["@vue-macros/volar"],
"vueMacros": {
"scriptSFC": true,
},
},
}
```
---
---
url: /macros/setup-component.md
---
# setupComponent
::: tip
`defineRender` cannot be disabled when using `setupComponent`.
Files in `node_modules` will be ignored by default.
:::
With `defineSetupComponent`, `
````
### There are two places to define
1. The first line of the script setup block.
````vue
````
2. Above the `export default` expression.
::: tip
This feature depends on `exportRender`, and make sure `exportRender` is not disabled.
:::
````vue
````
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/setup-sfc.md
---
# setupSFC
::: tip
If you're using `setupSFC`, then `defineRender` cannot be disabled.
:::
| Features | Supported |
| :----------------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript / Volar | :white_check_mark: |
## Setup
::: code-group
```ts {7-14} [Vite]
// vite.config.ts
import Vue from '@vitejs/plugin-vue'
import VueMacros from 'vue-macros/vite'
export default defineConfig({
plugins: [
VueMacros({
plugins: {
vue: Vue({
include: [/\.vue$/, /\.setup\.[cm]?[jt]sx?$/],
// ⬆️ setupSFC pattern need to be added
}),
},
}),
],
})
```
```ts {6-13} [Rollup]
import Vue from 'unplugin-vue/rollup'
import VueMacros from 'vue-macros/rollup'
export default defineConfig({
plugins: [
VueMacros({
plugins: {
vue: Vue({
include: [/\.vue$/, /\.setup\.[cm]?[jt]sx?$/],
// ⬆️ setupSFC pattern need to be added
}),
},
}),
],
})
```
```[🚧 esbuild]
🚧
```
```[🚧 Webpack]
🚧
```
:::
## Basic Usage
```tsx twoslash
// Foo.setup.tsx
defineProps<{
foo: string
}>()
defineEmits<{
(evt: 'change'): void
}>()
export default () => (
Hello World
)
```
## Volar Configuration
```jsonc {3,5} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"setupSFC": true,
},
},
}
```
---
---
url: /features/short-bind.md
---
# shortBind
`:value` -> `:value="value"`
Same-name shorthand for binding prop. If the attribute has the same name with the JavaScript value being bound, the syntax can be further shortened to omit the attribute value.
For Vue >= 3.4, this feature will be turned off by default.
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :x: |
| Volar Plugin | :white_check_mark: |
## Usage
### Basic Usage
```vue twoslash
```
### With `shortVmodel`
```vue
```
## Volar Configuration
```jsonc {3} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
},
}
```
---
---
url: /macros/short-emits.md
---
# shortEmits
Simplify the definition of emits.
For Vue >= 3.3, this feature will be turned off by default.
| Features | Supported |
| :--------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Vue 2 | :white_check_mark: |
| TypeScript | :white_check_mark: |
## Basic Usage
```vue twoslash
```
Using type `ShortEmits` or for short `SE`.
```vue twoslash
```
## Difference with Official Version
- function style of declaration is not supported by official version.
---
---
url: /macros/short-vmodel.md
---
# shortVmodel
A shorthand for `v-model`.
`v-model` -> `::` / `$` / `*`
If you have any questions about this feature, you can comment on [RFC Discussion](https://github.com/vuejs/rfcs/discussions/395).
| Features | Supported |
| :----------: | :----------------: |
| Vue 3 | :white_check_mark: |
| Nuxt 3 | :white_check_mark: |
| Vue 2 | :x: |
| Volar Plugin | :white_check_mark: |
## Options
```ts
interface Options {
/**
* @default '$'
*/
prefix?: '::' | '$' | '*'
}
```
## Usage
### `$` Dollar Sign (Default)
```vue
```
### `::` Double Binding
```vue
```
### `*` Asterisk Sign
```vue
```
## Volar Configuration
```jsonc {3,5-7} [tsconfig.json]
{
"vueCompilerOptions": {
"plugins": ["vue-macros/volar"],
"vueMacros": {
"shortVmodel": {
"prefix": "$",
},
},
},
}
```
## Known Issues
- Prettier will format `::=` to `:=` (e.g. `` -> ``). The comment `` is required if prefix is `::`.
---
---
url: /volar/template-ref.md
---
# templateRef
Automatically infer type for `templateRef` (from [VueUse](https://vueuse.org/core/templateRef/))
and `useTemplateRef` (Vue 3.5+).
::: warning
This feature is officially supported since Volar (`vue-tsc`) v2.1.0.
Vue Macros is no longer offering this feature as a plugin.
:::
| Features | Supported |
| :------: | :----------------: |
| Volar | :white_check_mark: |
## Basic Usage
::: code-group
```vue [App.vue] twoslash
```
<<< ./template-ref.md#comp{ts} [Comp.ts]
:::
## Volar Configuration
No configuration required.
---
---
url: /macros/index.md
---
# Usage
List of all available macros.
Please make sure `vue-macros` is set up correctly. If you haven't yet, read [Getting Started](../guide/getting-started.md) first.
## Implemented by Vue 3.3
- [defineOptions](./define-options.md)
- [defineSlots](./define-slots.md)
- [shortEmits](./short-emits.md)
## Stable Features
- [defineModels](./define-models.md)
- [defineProps](./define-props.md)
- [definePropsRefs](./define-props-refs.md)
- [defineRender](./define-render.md)
- [shortVmodel](./short-vmodel.md)
## Experimental Features
- [defineProp](./define-prop.md)
- [defineEmit](./define-emit.md)
- [setupComponent](./setup-component.md)
- [setupSFC](./setup-sfc.md)
- [chainCall](./chain-call.md)
- [defineStyleX](./define-stylex.md)