探索 Vue 最新功能:Vue Macros

你或许不曾留意到的 Vue 最新特性:Vue Macros

Vue3 曾有一项颇具激进性的 RFC 计划:消除使用 ref 时的 .value。然而,这一提案后来遭遇了许多反对声音,认为 Vue 修改了 JavaScript 语法的含义。最终,这一功能演变成了 $ref,而 Macros 则成为了配置该功能的关键所在。

事实上,Vue3 中涌现了许多先进的功能或处于灰度测试阶段的特性,这些特性都将通过 Vue Macros 插件来实现。因此,我们可以通过该插件提前体验未来的 Vue 特性。

你可以在官网了解更多:vueMacros

如何配置 Macros

Macros 是一个插件,首先需要通过 npm i -D unplugin-vue-macros 进行安装。接下来,在具体的打包器中配置,比如我目前使用的是 vite,因此我们直接看 vite 的配置:

typescript<code><em>// vite.config.ts</em> <strong>import</strong> <strong>VueMacros</strong> <strong>from</strong> 'unplugin-vue-macros/vite' <strong>import</strong> <strong>Vue</strong> <strong>from</strong> '@vitejs/plugin-vue' <strong>export</strong> <strong>default</strong> <strong>defineConfig</strong>({ plugins: [ <strong>VueMacros</strong>({ plugins: { vue: <strong>Vue</strong>(), }, }), ] })</code>

从这个配置方法来看,实际上它在 Vue 插件外层包了一层。具体的源码实现超出了本文的讨论范围,我们来看一下它提供了哪些有趣的功能:

  • Macros 提供了什么
  • 【稳定】betterDefine:支持引入类型Vue3 的 props 最初是不支持引入外部类型的,因此有了这一提案。不过我记得好像在 3.3 版本中就已经解决了这个问题,知道详情的可以告诉我
<script setup lang="ts"> 
    import type { BaseProps } from './types' 
    
    interface Props extends BaseProps { foo: string } 
    
    defineProps<Props>() 
</script>

【稳定】$defineProps:让 props 可以直接解构

我们都知道,在普通的 Vue3 中,props 是不能解构的,解构会失去响应性,因此有了这一提案。

const {a} = $defineProps({
    a:{type:String},
    b:{type:Boolean}
})
console.log(a.valu

实际上,我们也可以使用 toRefs 来实现这个功能:

const props = defineProps({
    a:{type:String},
    b:{type:Boolean}
})
const {a} = toRefs(props)
console.log(a.value)

【实验】definePropdefineEmit:单个声明 prop 或 emit

这其实只是一个很小的功能点,我甚至觉得它与上一个功能是一样的,只是实现思路不同。它主要用于声明单个 prop 或 emit。

const a = defineProp('a',{type:String})
const b = defineProp('b',{type:String})
console.log(a.value,b.value)
  1. 【稳定】Reactivity Transform:减少 Ref 使用的心智负担
  2. 【实验】defineRender:让 Vue 更像 React如果说前面两个只是小功能、小技巧,那么这个 defineRender 就是一个颠覆性的更新。通过配置 JSX,我们可以不再需要使用数组嵌套的写法,而是直接写 JSX。
defineRender(
  <div>
    <span>Hello</span>
  </div>,
)

或者直接使用渲染函数:

defineRender(() => {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  )
})
  • 这种写法看起来很像 React。
  • 【实验】setupComponentsetupSFC:完全拥抱 JSX,与 React 类似当我觉得 defineRender 已经是我的想象极限时,Vue 的团队却更加激进了,甚至可以说是变成了 React。首先,按照文档,我们需要在 Vite 中进行一些配置,扩展 Vue 支持的文件后缀,新增 .setup 和 JSX。
typescript
export default defineConfig({ 
    plugins: [ 
    VueMacros({ 
        plugins: { 
            vue: Vue({ include: [/\.vue$/, /\.setup\.[cm]?[jt]sx?$/] }), 
            // ⬆️ 需要添加 setup 模式
            }, 
        }), 
     ], 
 })

这两种方法的使用基本一样,我就不再分开介绍了

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

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

  defineOptions({
    name: 'App',
  })

  return (
      <div>
        <h1>Hello World</h1>
      </div>
    )
})

setupSFC 则更加激进,无需再包裹 defineSetupComponent 这个函数了,甚至可以省略 script setup。看看下面这个例子:

typescript
// Foo.setup.tsx
defineProps<{
  foo: string
}>()

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

export default () => (
  <div>
    <h1>Hello World</h1>
  </div>
)
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容