Vue 项目中大量报红提示:JSX 元素类不支持特性,因为它不具有“props”属性。

如上报错,问题在于之前安装了 React 相关的东西,可能导致 TSX 解析环境混乱,因为 React 和 Vue 的 TSX 解析方式不同。

可以按照以下步骤彻底排查和修复:

1. 检查是否安装了 React 相关依赖

如果之前安装了 React 相关的依赖,比如 react,react-dom,@types/react,Vue 的 TSX 解析可能会受到影响。

npm list --depth=0 | grep react

如果存在相关依赖,彻底删除: 

npm uninstall react react-dom @types/react

然后 清理依赖 并重新安装:

rm -rf node_modules package-lock.json pnpm-lock.yaml yarn.lock
npm cache clean --force
npm install
2. 确保 TypeScript 版本正确

Vue 3 的 JSX 解析需要 TypeScript >= 5.x,如果版本过低,可能会导致 "XX 不能用作 TSX 组件" 的错误。

检查 TypeScript 版本

npx tsc -v

如果版本低于 5.x 建议升级:

npm install typescript@latest -D
3. 确保正确安装 Vue 相关的 JSX 支持

Vue 默认不支持 JSX,需要安装 @vue/babel-plugin-jsx 才能正确解析 JSX 语法。

安装 Vue 相关的 JSX 依赖:

npm install @vue/babel-plugin-jsx -D

然后,在 babel.config.js 里启用:

module.exports = {
  plugins: ["@vue/babel-plugin-jsx"],
};

如果使用的是 Vite,还需要安装:

npm install @vitejs/plugin-vue-jsx -D

然后在 vite.config.ts 里添加:

import vueJsx from "@vitejs/plugin-vue-jsx";

export default defineConfig({
  plugins: [vueJsx()],
});

按照这个顺序排查,应该就能解决问题了!

4. 再补充一点(关键)

如果上述解决不了,那就在 tsconfig.json 文件下添加:

"jsxFactory": "h",

为什么呢?这其实是 Vue JSX 和 TypeScript 的编译机制不一致导致的。 

因为默认情况下,TypeScript 会将 JSX 编译成 React 风格的代码(即调用 React.createElement()),而不是 Vue 需要的 h() 函数!

所以当没有添加 jsxFactory: "h",TypeScript 就不知道我们要用 Vue,而是默认以为在用 React。这就导致:

  • Vue 组件没有 React 的 props 类型结构;
  • TypeScript 无法理解写的 JSX 是 Vue 的组件;

所以就报出类似:JSX 元素类不支持特性,因为它不具有“props”属性。

具体细节

🎯 没设置 jsxFactory 时,TS 编译 JSX 的行为:

默认情况下,TypeScript 会把如下 JSX:

<MyComponent title="Hello" />

编译成:

React.createElement(MyComponent, { title: "Hello" });

但在 Vue 中,应该是:

h(MyComponent, { title: "Hello" });

jsxFactory: "h" 的作用是告诉 TypeScript:“别用 React.createElement 了!我要用 Vue 的 h() 来编译 JSX!”

这样 TypeScript 就能正确识别 h() 是 Vue 的创建函数,对 Vue 组件进行类型推导,就不会报 props 错了。

关键

如果使用 Vue 3 + JSX,建议确保以下几项配置都正确:

1、tsconfig.json

{
  "compilerOptions": {
    "jsx": "preserve",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment"
  }
}

2、vite.config.ts

确保启用了 Vue 的 JSX 插件:

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

export default defineConfig({
  plugins: [vue(), vueJsx()],
})
补充说明:为啥 Vue 官方默认不加这个?

因为 Vue 的 SFC(单文件组件)并不使用 JSX,只有在写 .tsx 或 .jsx 的时候才需要加这些配置。

5. 小 Tip
jsxFactory: "h"

jsxFactory 指定了 JSX 元素应该使用哪个函数作为工厂来创建元素。默认情况下,React 使用 React.createElement 作为工厂函数,而在 Vue 3 中,我们通常使用 h 作为 JSX 元素的工厂函数。

为什么使用 h?

在 Vue 3 中,h 是 createVNode 的一个简写,h 函数负责创建虚拟 DOM 节点。它是 Vue 中处理 JSX 的标准工厂函数。当在 Vue 3 项目中使用 JSX 时,h 就是构建组件或 HTML 元素的函数。

所以,"jsxFactory":"h" 的作用就是告诉 TypeScript 在编译 JSX 时,应该用 h 函数来处理 JSX 元素的创建。

举个 🌰:

import { h } from 'vue'

const MyComponent = () => {
  return <div>Hello, world!</div> // 这里会被转换成 h('div', null, 'Hello, world!')
}
jsxFragmentFactory: "Fragment"

jsxFragmentFactory 指定了在 JSX 中使用 <> 和 </>(即 Fragment)时,应该使用哪个函数来生成对应的虚拟节点。

为什么使用 Fragment?

在 Vue 3 中,Fragment 是一个特殊的 Vue 组件,它不渲染任何元素,只是一个包裹多个子节点的容器。这使得可以在 JSX 中返回多个根节点,而无需使用额外的元素包裹它们。

Fragment 是 Vue 3 内置的功能,用于支持 JSX 语法中的片段(Fragment),即没有根节点的多个子节点。

"jsxFragmentFactory":"Fragment" 的作用就是告诉 TypeScript 在编译 JSX 时,应该用 Fragment 来处理 JSX 中的片段。

举个 🌰:

import { Fragment } from 'vue'

const MyComponent = () => {
  return <>
    <div>First element</div>
    <div>Second element</div>
  </> // 这里会被转换成 Fragment([], [h('div', null, 'First element'), h('div', null, 'Second element')])
}

在这个例子中,<> 和 </> 包裹了两个 div 元素,Fragment 负责将它们组合在一起,而不会在 DOM 中创建额外的父节点。

这两个选项是配合 Vue 3 和 TypeScript 使用 JSX 时非常重要的配置项,确保代码能正确编译和运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值