使用方法
HTML转JSX转换器是「粘贴、设缩进、点转换」四步:
- 在左边「待转换的 HTML」里粘贴你的片段。打开页面就有一份演示片段(div、img、label、input、br 共五行),可直接改。
- 「缩进空格数」填 2~8,默认 2。它决定每行前面补几个空格,只影响排版,不影响语义。
- 两个开关按需勾:想把
value、checked改成非受控写法就勾第一项;默认已勾第二项,会把<!-- 注释 -->转成 JSX 注释写法。 - 点「转换」,或在文本框里按 Ctrl/Cmd + Enter(Enter 留给换行)。结果出现在右边,按「复制结果」整段拿走。
HTML转JSX转换器能解决什么
它解决「把设计稿或旧页面的 HTML 搬进 React 组件时,属性名一个个手改」的重复劳动:
- 保留字冲突:
class和for在 JavaScript 里是关键字,直接搬到 JSX 会报错,本页统一改成className、htmlFor。 - 多词属性大小写:
readonly、maxlength、tabindex这类在 JSX 里要写成小驼峰readOnly、maxLength、tabIndex,手工改很容易漏掉一个。 - 标签必须闭合:HTML 里
<br>、<img>、<input>可以不写结束标签,JSX 里必须写成<br />形式,否则解析失败。 - style 写法不同:HTML 的
style="color:red;font-size:14px"在 JSX 里必须是对象style={{color:'red',fontSize:'14px'}},字符串会直接报错。 - 缩进重排:从浏览器「检查元素」里复制出来的代码经常缩进混乱,转换时按标签嵌套层级重排一遍,粘进组件文件不用再手工对齐。
本页不做的事:不做语法校验,转换结果不保证一定能通过 ESLint;不处理 <script> 里的 JS 逻辑;不帮你补 onChange;不做 JSX 转回 HTML 的反向转换。它改的是标签与属性的写法,不是代码逻辑。
原理和变量
① 用了哪个具体函数:属性解析用一次 String.prototype.replace 配合捕获组正则,把每个「属性名 = 属性值」逐个抽出来,再查一张二十余条的属性映射表改写;标签是否自闭合由一份十三项的 void 元素名单决定;缩进按每行开标签与闭标签的数量差重排。整页没有引入 Babel、htmlparser2 或任何解析器,只有正则分词加逐行计数。
② 关键参数为什么这样取:只改属性名、不改属性顺序,是为了让转换结果与原 HTML 一一对应,方便你对照 diff 时一眼看出改了什么。data-* 与 aria-* 这类带连字符的属性原样保留,因为 JSX 本身就支持连字符属性名,改写成驼峰反而会破坏无障碍语义与测试选择器。style 必须转成对象,因为 JSX 的 style 只接受对象,传字符串会直接抛错。
③ 遵循哪个标准:属性名改写遵循 React 官方 JSX 的 DOM 属性命名约定——避开 class、for 这两个 JavaScript 保留字,其余多词属性统一改小驼峰;void 元素名单取自 HTML 规范中「不允许有结束标签」的元素集合;缩进只是排版,不参与语义,所以放在最后一步处理。
④ 输入怎么变成输出:演示片段里 <div class="card" data-id="1"> 变成 <div className="card" data-id="1">;<label for="user-name"> 变成 <label htmlFor="user-name">;<input type="text" value="小明" readonly> 变成 <input type="text" value="小明" readOnly />;<br> 变成 <br />;data-id 保持不变。
⑤ 边界与阈值:缩进空格数限 2~8,默认 2;单次输入超过 20000 字符会提示「内容过长,请分段转换」;输入为空或只含空白会提示「请先粘贴 HTML 片段」。style 值按分号拆项、每项按第一个冒号拆键值,若某项里含有冒号之外无法拆分的片段(例如 background:url(...) 这种本身含冒号的值),拆分可能偏移,需要你手动复核。
⑥ 常见误用的正确解释:以为转换完就能直接放进组件是最大的误区——value 属性若没有配套的 onChange,React 会把它当成受控组件并给出警告,此时应该勾上「改 defaultValue」或手工补上 onChange。另一个常见错误是自闭合后又补了结束标签,写成 <br /></br>。
完整示例(数值仅作演示)
演示输入(缩进 2 个空格、开启注释转换、不开启 defaultValue):
<div class="card" data-id="1">
<img src="cover.png" alt="封面">
<label for="user-name">姓名</label>
<input type="text" value="小明" readonly>
<br>
</div>
逐行推导后的输出:
- 第一行:
class→className,data-id保留 →<div className="card" data-id="1">。 - 第二行:
img属于无结束标签元素,补斜杠 →<img src="cover.png" alt="封面" />。 - 第三行:
for→htmlFor→<label htmlFor="user-name">姓名</label>。 - 第四行:
readonly→readOnly,input补斜杠 →<input type="text" value="小明" readOnly />。 - 第五行:
br补斜杠 →<br />。
合起来就是右侧默认展示的那五行的结果,可与默认输出逐字核对。
输入范围与对照表
下表列出本页会主动改写的属性名映射,前 12 行是最常遇到的,后 4 行继续补充;带连字符的属性与未知属性一律原样保留。
| HTML 属性 | JSX 属性 | 改写原因 |
|---|---|---|
| class | className | class 是 JavaScript 关键字 |
| for | htmlFor | for 是 JavaScript 关键字 |
| tabindex | tabIndex | 多词属性改小驼峰 |
| readonly | readOnly | 多词属性改小驼峰 |
| maxlength | maxLength | 多词属性改小驼峰 |
| minlength | minLength | 多词属性改小驼峰 |
| autofocus | autoFocus | 多词属性改小驼峰 |
| autoplay | autoPlay | 多词属性改小驼峰 |
| colspan | colSpan | 多词属性改小驼峰 |
| rowspan | rowSpan | 多词属性改小驼峰 |
| enctype | encType | 多词属性改小驼峰 |
| accesskey | accessKey | 多词属性改小驼峰 |
| contenteditable | contentEditable | 多词属性改小驼峰 |
| spellcheck | spellCheck | 多词属性改小驼峰 |
| frameborder | frameBorder | 多词属性改小驼峰 |
| allowfullscreen | allowFullScreen | 多词属性改小驼峰 |
映射表之外还有 srcset、novalidate、crossorigin、referrerpolicy 等十余条同样按小驼峰改写;未知属性与 data-*、aria-* 一律不动。
结果边界和舍入
输出性质:转换结果是纯文本字符串,不含引号包裹,可直接粘进 .jsx 文件。属性值的引号保持原样(双引号还是双引号),只有 style 会被改写为对象写法。
什么时候会提示:输入为空或只有空白时提示「请先粘贴 HTML 片段」;输入超过 20000 字符时提示「内容过长,请分段转换」;缩进不在 2~8 之间时提示并回退到 2。本页不做语法校验,所以非法的标签嵌套不会报错,只会原样输出。
精度与确定性:转换是纯字符串改写,没有任何数值计算,因此不存在舍入问题;同样的输入必然得到同样的输出,结果可重复。
结果性质:这是写法层面的机械转换,不是代码审查。转换后仍请用编辑器的语法检查、ESLint 和一次真实渲染来验收,尤其是 style 与事件属性这两类。
常见问题
为什么不直接把 class 保留下来?
因为 class 是 JavaScript 的保留字,JSX 最终要编译成 JavaScript 函数调用,用 class 作属性名会触发语法错误,所以 React 约定改叫 className。
data-* 和 aria-* 为什么没被改写?
JSX 支持带连字符的属性名,改写反而会破坏无障碍语义和自动化测试用的选择器,所以本页对这两类属性一律原样保留。
style 属性为什么要变成对象?
JSX 的 style 只接受对象,传字符串会在运行时直接报错。本页按分号拆项、按第一个冒号拆键值,再把属性名改小驼峰,拼成对象写法。
value 什么时候该改成 defaultValue?
当表单元素没有配套 onChange 时。带 value 而没有 onChange 会被 React 视为受控组件并给出警告,勾上「改 defaultValue」即可变成非受控写法。
缩进用制表符可以吗?
本页统一输出空格,缩进空格数可在 2~8 之间选。需要制表符的话,粘进编辑器后用它自带的缩进转换功能换一次即可。
HTML 注释是怎么处理的?
默认开启转换,注释会被改写成 JSX 支持的注释写法。若你希望保留原始 HTML 注释文本,取消勾选「把 HTML 注释转成 JSX 注释」即可。
输入很长会被截断吗?
不会截断,但超过 20000 字符会提示「内容过长,请分段转换」并停止处理,避免一次处理过大文本造成卡顿。分几段转换再拼接即可。
我的源码会被上传吗?
不会。转换完全在浏览器内完成,不发起任何网络请求,刷新即清空。可以在 Network 面板复查,点「转换」时不会有任何请求发出。
相关工具
- YAML转JSON转换器:配置片段搬进前端项目时先用它定型。
- JSON转TypeScript接口:给组件 props 补类型定义。
- chmod权限计算器Unix权限:部署静态资源时核对权限位。
- JavaScript压缩:转换后的组件打包前压一遍。
- 文本转数据URI转换器:把小图标内联进样式属性。
- Slugify字符串工具:给转换出来的组件文件起名。
- 环境变量转JSON转换器:整理构建期注入的配置。