UzumakiItachi
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

UzumakiItachi

起风了,唯有努力生存。
首页
  • JavaSript
  • Vue

    • Vue2
    • Vue3
  • React

    • React_18
  • WebPack
  • 浏览器相关
  • 工程化相关
  • 工作中遇到的问题以及解决方案
  • Git
  • 面试
  • 学习
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 个人产出
  • 实用工具
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 手写组合api reactive和ref
  • vue3的计算属性和监视
  • history 路由404,nginx配置
  • 手写Vue3响应式原理
  • 手写Vue3计算属性和Watch
  • vue3在jsx中优雅的使用动态组件
    • 前言
    • 在vue3+vite项目中使用jsx
    • Icon组件
    • h
    • resolveComponent
  • 《Vue3》
hanhanbuku
2023-08-31
目录

vue3在jsx中优雅的使用动态组件

# 前言

在做项目的时候使用了element的图标库,后续又想扩展一些自己图标库上去。但由于后面引入的图标库的使用方式和element的有区别,所以选择封装一个图标组件来进行渲染。组件是通过jsx写的,于是在开发过程中就遇到了动态组件失效的问题。下面就来介绍一下在jsx中该如何去使用动态组件

# 在vue3+vite项目中使用jsx

首先需要安装一下编译jsx的插件

pnpm i @vitejs/plugin-vue-jsx -D
1

然后再配置文件中使用一下这个插件

import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
    plugins:[
        vue(),
        vueJsx(),
        ...
    ]
})
1
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>

1
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('组件名称'))}
1

这里记录一下小tips:最近vue和react交替开发,在写vue的jsx的时候先入为主的将react函数式组件的思维带入进去了,导致忘记声明props了。搞的半天接受不到父组件传入的props....还以为jsx有什么特殊的姿势去接受props呢,结果整半天是没声明哈哈哈哈

编辑 (opens new window)
上次更新: 2023/08/31, 17:34:42
手写Vue3计算属性和Watch

← 手写Vue3计算属性和Watch

最近更新
01
小程序实现全局状态管理
07-09
02
前端检测更新,自动刷新网页
06-09
03
swiper渲染大量数据的优化方案
06-06
更多文章>
Theme by Vdoing | Copyright © 2023-2025 UzumakiItachi | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式