vue3在jsx中优雅的使用动态组件
# 前言
在做项目的时候使用了
element
的图标库,后续又想扩展一些自己图标库上去。但由于后面引入的图标库的使用方式和element
的有区别,所以选择封装一个图标组件来进行渲染。组件是通过jsx
写的,于是在开发过程中就遇到了动态组件失效的问题。下面就来介绍一下在jsx
中该如何去使用动态组件
# 在vue3+vite项目中使用jsx
首先需要安装一下编译jsx
的插件
pnpm i @vitejs/plugin-vue-jsx -D
然后再配置文件中使用一下这个插件
import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins:[
vue(),
vueJsx(),
...
]
})
2
3
4
5
6
7
8
9
下面就可以开心的去使用jsx
来编写代码啦。
# Icon组件
<script lang="tsx">
import { defineComponent, h, resolveComponent } from 'vue'
export default defineComponent({
name: 'NcIcon',
props: {
keys: {
type: String,
default: '',
},
},
setup(props: {
keys: string
}, ctx) {
return () => props.keys && props.keys.indexOf('nc-') !== -1 ? (
<span class={['iconfont', props.keys]}></span>
) : (
<el-icon>
{h(resolveComponent(props.keys))}
</el-icon>
)
},
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
需要把script
标签的lang
改为tsx
,文件后缀正常使用.vue
就行。
组件非常简单,就是区分了一下传入的keys
来渲染不同的图标。正常来说在el-icon
里会去选择使用component
组件来动态渲染element
的图标,但是由于图标组件没有在这个组件中注册,而是注册在全局,所以在jsx
中使用的话,
并不会去渲染组件,而是把你传入的keys
当成字符串
输出了。后面经过官网查阅资料发现了这个api
。
# h
这个api
大家都知道,他就是用来创建vnode
的,也就是俗称的虚拟DOM
。最终交由render
渲染的就是他。
# resolveComponent
重点是这个函数,由于h函数需要传入一个组件实例或者一个标签类型,很显然我们传入的字符串是不符合要求的,所以需要用到resolveComponent
函数。
官网对他的解释是:按名称手动解析已注册的组件。我们的图标组件已经注册在全局了,这个函数刚好可以通过字符串解析出以注册的组件。这不就正好能达成需求了嘛。
以后在jsx
中想动态渲染都可以通过这个方案,当然前提是组件你已经注册了。
{h(resolveComponent('组件名称'))}
这里记录一下小tips:最近vue
和react
交替开发,在写vue
的jsx
的时候先入为主的将react
函数式组件的思维带入进去了,导致忘记声明props
了。搞的半天接受不到父组件传入的props
....还以为jsx有什么特殊的姿势去接受props
呢,结果整半天是没声明哈哈哈哈