我们都知道vue3
是支持用jsx/tsx
,但是好像从来都没有人告诉我们应该怎么运用到项目当中,下面是我觉得不错的一种使用方式,分享给大家。
GTP:
在Vue中,通常使用JSX来描述组件的模板。JSX是JavaScript XML的缩写,它允许你在JavaScript中编写类似HTML的代码,用于描述UI。TSX则是TypeScript的扩展,用于在TypeScript中编写JSX。虽然Vue通常使用单文件组件(.vue文件),但是你也可以选择使用JSX来编写Vue组件。 TSX则是用于在TypeScript中编写JSX的文件扩展名。
vue3官网 #JSX / TSX:传送门
我们先把plugin-vue-jsx
安装到项目中
npm i @vitejs/plugin-vue-jsx -D
or
yarn add @vitejs/plugin-vue-jsx -D
提示:文章会以vue3 + vite + ts项目诉说
安装完插件后,我们需要在vite.config.ts
的plugins
中配置一下,之后就可以正常使用了。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';
export default defineConfig({
plugins: [
vue(),
vueJsx()
]
})
我们先封装一个用来渲染jsx
的组件
src
|-components
|-JsxRender
|-JsxRender.vue
代码很简单,就抛出一个render
回调钩子去渲染jsx
<script lang="ts">
export default {
props: {
params: {
type: Object,
},
render: {
type: Function,
},
},
render() {
return this.render(this.params)
},
}
</script>
封装完之后,我们可以轻而易举的以组件的形式去渲染jsx
了,是不是特别简单?需要注意的是script
标签里的语言要写成lang="tsx"
,另外demo项目用来unplugin-vue-components
,所以components
文件夹下的组件不用引入就可直接使用,没用过的后续可以下载我的demo看看
代码:
<script setup lang="tsx">
const jsxRenderParams = {
title: '这是jsx渲染出来的文本'
}
function renderFn(data) {
return <p class="jsx-render">{data.title}</p>
}
</script>
<template>
<jsxRender :params="jsxRenderParams" :render="renderFn" />
</template>
<style lang="scss" scoped>
.jsx-render {
color: #41B883;
}
</style>
效果:
比方说我们做项目经常用到的element table
表单,我们就可以留一个口子给jsx
去动态的设置el-table-column
,代码如下:
src
|-components
|-JsxTable
|-JsxTable.vue
JsxTable.vue:
<script lang="ts" setup>
interface Columns {
prop: string
label: string
renderCell?: Function
}
interface Props {
columns: Columns[]
data: Record<string, any>[]
}
const props = withDefaults(defineProps<Props>(), {
columns: () => [],
data: () => [],
})
</script>
<template>
<el-table :data="props.data">
<el-table-column v-for="item in props.columns" :key="item.prop" :label="item.label">
<template #default="{ row }">
<jsxRender v-if="item.renderCell" :params="row" :render="item.renderCell" />
<span v-else>{{ row[item.prop] }}</span>
</template>
</el-table-column>
</el-table>
</template>
接着我能就可以在columns
属性绑定的数组对象里写jsx
代码了,我们JsxTable
组件里封装的渲染函数叫renderCell
,所以当我们想要动态渲染某一列时,只需要在renderCell
方法里返回jsx
代码就好了,
代码如下:
<script setup lang="tsx">
const columns = [
{
prop: 'num',
label: '序号',
},
{
prop: 'tooltip',
label: 'el-tooltip',
renderCell: (row) => {
return (
<el-tooltip
content={row.tooltip.content}
>
<span>{row.tooltip.name}</span>
</el-tooltip>
)
}
},
{
prop: 'progress',
label: 'el-progress',
renderCell: (row) => {
return (
<el-progress percentage={row.progress.percentage} status={row.progress.status} />
)
}
},
{
prop: 'operate',
label: '操作',
renderCell: (row) => {
return (
<el-button type="primary" link onClick={() => clickOperate(row)}>编辑</el-button>
)
}
}
]
const tableData = [
{
num: '1',
tooltip: {
name: '雷总',
content: '雷军造车,天命所归,雷字带电,军字带车。'
},
progress: {
percentage: 100,
status: 'success'
},
msg: '这TMD绝对是捣乱的是吧'
},
{
num: '2',
tooltip: {
name: '卢总',
content: '新手还在看小米,老手已经开始等红米汽车了'
},
progress: {
percentage: 50,
status: ''
},
msg: '干翻友商小米'
},
]
function clickOperate(item) {
ElMessage({
message: item.msg,
type: 'success',
})
}
</script>
<template>
<JsxTable :columns=columns :data=tableData />
</template>
demo效果:(之后如果你遇到类似的组件如el-descriptions,你就可以根据这个风格去封装组件了?(?????)?)
有积分交一下公粮,没积分的去gitee
?CSDN:vue3-tsx 传送门
?Gitee:vue3-tsx 传送门