vue 文件中无法直接写 JSX,可先在 tsx 文件中写 JSX,再导入 vue 文件,并用共用的 render 函数渲染。
完整范例代码如下,三个文件都在同一目录下。
test.vue
<template> <component v-model="value" :is="fontFamilyList.component" v-bind="fontFamilyList" > <template v-if="fontFamilyList.options"> <component :is="fontFamilyList.subComponent" v-for="(option, k) in fontFamilyList.options" :key="k" :label="option.label" :value="option.value" > <RenderVnode :vNode="option.text" /> </component> </template> </component> </template> <script setup lang="ts"> import { ref } from "vue"; import RenderVnode from "./RenderVnode"; import { fontFamilyOptions } from "./fontFamily"; const fontFamilyList = { clearable: true, placeholder: "请选择字体", component: "el-select", subComponent: "el-option", options: [...fontFamilyOptions], }; const value = ref(""); </script>
fontFamily.tsx
import type { VNode } from "vue"; const fontFamilyArr = [ { text: "宋体", value: '"SimSun","STSong"' }, { text: "黑体", value: '"SimHei","STHeiti"' }, { text: "楷体", value: '"KaiTi","STKaiti"' }, { text: "仿宋", value: '"FangSong","STFangsong"' }, ]; export const fontFamilyOptions = fontFamilyArr.map((font) => { return { value: font.value, label: font.text, // 此处语法为 JSX text: ( <span style={{ fontFamily: font.value }}>{font.text}</span> ) as VNode, }; });
RenderVnode.ts
import { defineComponent } from "vue"; const RenderVnode = defineComponent({ props: { vNode: { type: [Object, String], required: true, }, }, render() { return this.vNode; }, }); export default RenderVnode;