English | 简体中文
Extend macros and syntax sugar in Vue.
- ✨ Extend macros and syntax sugar in Vue.
- 💚 Supports both Vue 2 and Vue 3 out-of-the-box.
- 🦾 Full TypeScript support.
- ⚡️ Supports Vite, Webpack, Vue CLI, Rollup, esbuild and more, powered by unplugin.
npm i unplugin-vue-macros -D
Vite (first-class support)
// vite.config.ts
import VueMacros from 'unplugin-vue-macros/vite'
import Vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [VueMacros(), Vue()],
})
Rollup (first-class support)
// rollup.config.js
import Vue from 'unplugin-vue/rollup'
import VueMacros from 'unplugin-vue-macros/rollup'
export default {
plugins: [VueMacros(), Vue()], // must be before Vue plugin!
}
esbuild
// esbuild.config.js
import { build } from 'esbuild'
build({
plugins: [
require('unplugin-vue-macros/esbuild')(), // must be before Vue plugin!
require('unplugin-vue/esbuild')(),
],
})
Webpack
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-macros/webpack')(), // must be before Vue plugin!
require('unplugin-vue/webpack')(),
],
}
Vue CLI
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [require('unplugin-vue-macros/webpack')()],
},
}
Introduce a macro in <script setup>
, defineOptions
,
to use Options API in <script setup>
, specifically to be able to set name
, props
, emits
and render
in one function.
Note: if you only need
defineOptions
, the standalone version is better for you.
If you support this feature, you can go to RFC Discussion and hit like 👍 or comment. Thanks!
<script setup lang="ts">
import { useSlots } from 'vue'
defineOptions({
name: 'Foo',
inheritAttrs: false,
})
const slots = useSlots()
</script>
Output
<script lang="ts">
export default {
name: 'Foo',
inheritAttrs: false,
}
</script>
<script setup>
const slots = useSlots()
</script>
<script setup lang="tsx">
defineOptions({
render() {
return <h1>Hello World</h1>
},
})
</script>
Output
<script lang="tsx">
export default {
render() {
return <h1>Hello World</h1>
},
}
</script>
Introduce a macro in <script setup>
, defineModel
.
To be able define and change v-model
props as the same as normal variable.
Warning: Reactivity Transform is required. You should enable it first. Otherwise, it will lose the reactivity connection.
Warning: Assignment expression is only supported in
<script setup>
block. In other words invalid in<template>
.
<script setup lang="ts">
let { modelValue, count } = defineModel<{
modelValue: string
count: number
}>()
console.log(modelValue)
modelValue = 'newValue'
count++
</script>
Output
<script setup lang="ts">
const { modelValue, count } = defineProps<{
modelValue: string
modelValue: number
}>()
const emit = defineEmits<{
(evt: 'update:modelValue', value: string): void
(evt: 'update:count', value: number): void
}>()
console.log(modelValue)
emit('update:modelValue', 'newValue')
emit('update:count', count + 1)
</script>
<script setup lang="tsx">
// JSX passed directly
defineRender(
<div>
<span>Hello</span>
</div>
)
// Or using render function
defineRender(() => {
return (
<div>
<h1>Hello World</h1>
</div>
)
})
</script>
If you want to reference a constant declared in <script setup>
, then this feature may help you.
If you support this feature, please go to Vue PR and hit like 👍. Thanks!
<script setup lang="ts">
const name = 'AppFoo'
defineOptions({
name,
})
</script>
Output
<script lang="ts">
const name = 'AppFoo'
export default {
name,
}
</script>
<script setup lang="ts">
const name = /* hoist-static */ fn() // a value that's even not a constant
defineOptions({
name,
})
</script>
Output
<script lang="ts">
const name = fn()
export default {
name,
}
</script>
Warning: Under experimental, use at your risk!
With defineSetupComponent
, <script setup>
code can be put in pure JS/TS(X) without Volar extension.
export const App = defineSetupComponent(() => {
defineProps<{
foo: string
}>()
defineEmits<{
(evt: 'change'): void
}>()
defineOptions({
name: 'App',
})
// ...
})
- The source map does not correspond properly.
- TypeScript support is not yet complete.
Warning: Under experimental, use at your risk!
Note:
defineOptions
is required. If you're usingsetupComponent
, thendefineOptions
cannot be disabled.
<script setup>
code can be put in pure JS/TS(X) without Volar extension.
Using Vite as an example:
// vite.config.ts
import VueMacros from 'unplugin-vue-macros/vite'
import Vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
VueMacros(),
Vue({
include: [/\.vue$/, /setup\.[cm]?[jt]sx?$/], // ⬅️ setupSFC pattern need to be added
}),
],
})
// Foo.setup.tsx
defineProps<{
foo: string
}>()
defineEmits<{
(evt: 'change'): void
}>()
export default () => (
<div>
<h1>Hello World</h1>
</div>
)
- The source map does not correspond properly in JSX/TSX files.
- TypeScript support is not yet complete.