- 本文链接:VueUse 中 createReusableTemplate 的妙用
- 版权声明: 本博客所有文章除特别声明外,均采用
BY-NC-SA 许可协议,转载请注明出处!
VueUse 中 createReusableTemplate 的妙用
2025/8/24大约 2 分钟
VueUse 中 createReusableTemplate 的妙用
日常开发中部分地方需要使用Render 渲染函数的写法即使用h
(也叫 createVNode) 来生成 VNode 虚拟节点,或者需要使用JSX/TSX的写法,对于不熟悉的人来说这 2 种写法很不友好,使用createReusableTemplate后就能大大弱化这 2 种写法的不便。
各写法比较
对于使用 Naive UI 的人来说,常用的菜单 Menu
、表格 Table
、选择器 Select
等部分都需要使用render
的写法,以最常用的表格 Table
自定义列的写法为例子:
h 函数写法
<template>
<NDataTable :columns="columns" :data="data" />
</template>
<script setup lang="ts">
import { h } from 'vue'
import { NButton, NDataTable, NPopover, NSpace } from 'naive-ui'
const columns = [
{
title: '名字',
key: 'name'
},
{
title: '操作',
key: 'action',
render: (row) => {
return h(NSpace, {}, [
h(
NPopover,
{ trigger: 'hover' },
{
default: () => '编辑',
trigger: () =>
h(
NButton,
{
round: true,
ghost: true,
size: 'small',
type: 'primary'
},
{ default: () => '编辑' }
)
}
),
h(
NPopover,
{ trigger: 'hover' },
{
default: () => '删除',
trigger: () =>
h(
NButton,
{
round: true,
ghost: true,
size: 'small',
type: 'error'
},
{ default: () => '删除' }
)
}
)
])
}
}
]
const data = [
{
name: 'liubing.me 1'
},
{
name: 'liubing.me 2'
}
]
</script>
TSX 写法
<template>
<NDataTable :columns="columns" :data="data" />
</template>
// lang需要使用tsx
<script setup lang="tsx">
import { NButton, NDataTable, NPopover, NSpace } from 'naive-ui'
const columns = [
{
title: '名字',
key: 'name'
},
{
title: '操作',
key: 'action',
render: (row) => {
return (
<NSpace>
<NPopover trigger="hover">
{{
default: () => '编辑',
trigger: () => (
编辑
)
}}
</NPopover>
<NPopover trigger="hover">
{{
default: () => '删除',
trigger: () => (
删除
)
}}
</NPopover>
</NSpace>
)
}
}
]
const data = [
{
name: 'liubing.me 1'
},
{
name: 'liubing.me 2'
}
]
</script>
createReusableTemplate 写法
解构createReusableTemplate()
,使用DefineActionTemplate
定义模板,然后在需要使用模板的地方使用UseActionTemplate
渲染模板,DefineActionTemplate
和UseActionTemplate
可以自己随便定义,这样就可以常用的template
写法去定义需要render
渲染的内容,使用非常方便。
<template>
<div>
<!-- 定义模板 -->
<DefineActionTemplate v-slot="{ row }">
<NSpace>
<NPopover trigger="hover">
<template #trigger>
<NButton round ghost size="small" type="primary">编辑</NButton>
</template>
编辑
</NPopover>
<NPopover trigger="hover">
<template #trigger>
<NButton round ghost size="small" type="error"> 删除 </NButton>
</template>
删除
</NPopover>
</NSpace>
</DefineActionTemplate>
<NDataTable :columns="columns" :data="data" />
</div>
</template>
<script setup lang="ts">
import { h } from 'vue'
import { createReusableTemplate } from '@vueuse/core'
import { NButton, NDataTable, NPopover, NSpace } from 'naive-ui'
const [DefineActionTemplate, UseActionTemplate] = createReusableTemplate()
const columns = [
{
title: '名字',
key: 'name'
},
{
title: '操作',
key: 'action',
render: (row) => h(UseActionTemplate, { row }) // 这里使用模板
// render: row => <UseActionTemplate row={row} /> // 如果lang是tsx,则使用这种写法
}
]
const data = [
{
name: 'liubing.me 1'
},
{
name: 'liubing.me 2'
}
]
</script>
总结
使用createReusableTemplate
后就不用怕写render
写法了,有一点需要注意的是定义的模板最好放在最上面,防止出现下面的错误:
Error: [VueUse] Failed to find the definition of reusable template
总之模板需要先定义在使用,比如上面的列子,如果将DefineActionTemplate
定义模板的内容放在<NDataTable :columns="columns" :data="data" />
下面,就会出现上面的异常。