Skip to content

lingdu1234/unplugin-vue-macros

 
 

Repository files navigation

unplugin-vue-macros npm

Unit Test

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'
// import VueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
  plugins: [
    VueMacros({
      plugins: {
        vue: Vue(),
        // vueJsx: VueJsx(), // if needed
      },
    }),
  ],
})


Rollup (first-class support)
// rollup.config.js
import Vue from 'unplugin-vue/rollup'
import VueMacros from 'unplugin-vue-macros/rollup'

export default {
  plugins: [
    VueMacros({
      plugins: {
        vue: Vue(),
        // vueJsx: VueJsx(), // if needed
      },
    }),
  ],
}


esbuild
// esbuild.config.js
import { build } from 'esbuild'

build({
  plugins: [
    require('unplugin-vue-macros/esbuild')({
      plugins: {
        vue: require('unplugin-vue/esbuild')(),
        // vueJsx: VueJsx(), // if needed
      },
    }),
  ],
})


Webpack
// webpack.config.js
module.exports = {
  /* ... */
  plugins: [
    require('unplugin-vue-macros/webpack')({
      plugins: {
        vue: require('unplugin-vue/webpack')(),
        // vueJsx: VueJsx(), // if needed
      },
    }),
  ],
}


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
  count: 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>

defineRender

Basic Usage

<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>

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',
  })

  // ...
})

Type Annotation

export const App: SetupFC = () => {
  defineProps<{
    foo: string
  }>()

  defineEmits<{
    (evt: 'change'): void
  }>()

  defineOptions({
    name: 'App',
  })
}

Known issues

  • The source map does not correspond properly.
  • TypeScript support is not yet complete.

setupSFC (⚠️ experimental)

Warning: Under experimental, use at your risk!

Note: defineOptions is required. If you're using setupComponent, then defineOptions cannot 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.
  • TypeScript support is not yet complete.

Sponsors

Related Libraries

License

MIT License © 2022 三咲智子

About

Explore and extend more macros and syntax sugar to Vue.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 95.2%
  • Vue 4.1%
  • Other 0.7%