 vue3在jsx中优雅的使用动态组件
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呢,结果整半天是没声明哈哈哈哈