配置添加tsx支持

1. 执行一下语句,添加支持tsx插件

yarn add -D @vitejs/plugin-vue-jsx

注意:这里需要特别说明一下,@vitejs/plugin-vue一定要在3.2.0或以下版本才能正常支持<script setup lang="tsx">中的JSX子组件。

2. 添加如下语句到tsconfig.jon

 "jsx": "preserve",
 "jsxFactory": "h",
 "jsxFragmentFactory": "React.Fragment",

完整配置如下:

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "jsxFactory": "h",
    "jsxFragmentFactory": "React.Fragment",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": [
      "ESNext",
      "DOM"
    ],
    "skipLibCheck": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "exclude": ["node_modules"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

3. 添加插件vueJsx()vite.config.ts中,完整配置如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from "@vitejs/plugin-vue-jsx";
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx()],
  resolve: {
    alias: { // 配置方式一
      "@": path.resolve(__dirname, "./src"),
    },
    alias: [ // 配置方式二
      {
        // 键必须以斜线开始和结束
        find: /^@\//,
        replacement: `${path.resolve(__dirname, './src')}/`
      },
    ]
  }
})

几中tsx的写法

方法一

import {Vue} from 'vue-class-component';
  
export default  class MenuItem extends Vue {
  
    render() {
        return <div>hello tsx</div>
    }
}

注意:这里有个小坑,该方式不能正确使用装饰器(decorators),参考这里

方式二

import {defineComponent} from 'vue'

export default defineComponent({
    setup(){
      
        // 这里使用()不用写return  如果是{}则需要写
        // 内部只能有一个跟标签,你可以使用<></>
        return () => (
            <div>hello tsx</div>
        )
    }
})

方法三

import {h, ref, defineProps} from "vue";
import styles from "./item.less"

let v = ref<string>("我是jsx写法");

let props = defineProps<{ data: any[] }>()
console.log(props)

const renderDom = (props: { data: any[] }) => {
    // setup fn
    return props.data.map((it, idx) => {
            if (it.children == null) return <el-menu-item key={idx}>{it.name}</el-menu-item>

            if (it.children.length == 1 && it.meta.showChildOnly) return renderDom({data: it.children})

            return <el-sub-menu key={it.path} >
                {{
                    title: () => it.name,
                    default: renderDom({data: it.children})
                }}
            </el-sub-menu>
        }
    )
};
renderDom.displayName = "Demo1" // 需要注意,如果不添加该属性,可能出现渲染问题

export default renderDom;

方法四

<script lang="tsx" setup>
const SubItem = () => {
  return <div>Menu</div>
}
</script>

<template lang="pug">
SubItem
</template>

参考资料