vue-macros
vue-macros copied to clipboard
Explore and extend more macros and syntax sugar to Vue.
unplugin-vue-macros 
English | 简体中文
Extend macros and syntax sugar in Vue.
Features
- ✨ 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.
Installation
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')()],
},
}
TypeScript Support
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["unplugin-vue-macros/macros-global" /* ... */]
}
}
Usage
defineOptions
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!
Basic Usage
<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>
JSX in <script setup>
<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>
defineModel
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>.
Basic Usage
<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>
hoistStatic
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!
Basic Usage
<script setup lang="ts">
const name = 'AppFoo'
defineOptions({
name,
})
</script>
Output
<script lang="ts">
const name = 'AppFoo'
export default {
name,
}
</script>
Magic Comments
<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>
setupComponent (⚠️ experimental)
Warning: Under experimental, use at your risk!
With defineSetupComponent, <script setup> code can be put in pure JS/TS(X) without Volar extension.
Basic Usage
export const App = defineSetupComponent(() => {
defineProps<{
foo: string
}>()
defineEmits<{
(evt: 'change'): void
}>()
defineOptions({
name: 'App',
})
// ...
})
Known issues
- [ ] The source map does not correspond properly.
- [ ] The render function cannot refer to variables. However, you can use the first argument of the render function to receive the context.
- [ ] TypeScript support is not yet complete.
setupSFC (⚠️ experimental)
Warning: Under experimental, use at your risk!
Note:
defineOptionsis required. If you're usingsetupComponent, thendefineOptionscannot be disabled.
<script setup> code can be put in pure JS/TS(X) without Volar extension.
Setup
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
}),
],
})
Basic Usage
// Foo.setup.tsx
defineProps<{
foo: string
}>()
defineEmits<{
(evt: 'change'): void
}>()
export default () => (
<div>
<h1>Hello World</h1>
</div>
)
Known issues
- [ ] The source map does not correspond properly in JSX/TSX files.
- [ ] The render function cannot refer to variables. However, you can use the first argument of the render function to receive the context.
- [ ] TypeScript support is not yet complete.
Sponsors
License
MIT License © 2022 三咲智子