你或许不曾留意到的 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)
【实验】defineProp
、defineEmit
:单个声明 prop 或 emit
这其实只是一个很小的功能点,我甚至觉得它与上一个功能是一样的,只是实现思路不同。它主要用于声明单个 prop 或 emit。
const a = defineProp('a',{type:String})
const b = defineProp('b',{type:String})
console.log(a.value,b.value)
- 【稳定】
Reactivity Transform
:减少 Ref 使用的心智负担 - 【实验】
defineRender
:让 Vue 更像 React如果说前面两个只是小功能、小技巧,那么这个defineRender
就是一个颠覆性的更新。通过配置 JSX,我们可以不再需要使用数组嵌套的写法,而是直接写 JSX。
defineRender(
<div>
<span>Hello</span>
</div>,
)
或者直接使用渲染函数:
defineRender(() => {
return (
<div>
<h1>Hello World</h1>
</div>
)
})
- 这种写法看起来很像 React。
- 【实验】
setupComponent
、setupSFC
:完全拥抱 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>
)
暂无评论内容