data-i18n必须显式覆盖所有可翻译属性并带对应后缀,lang需逐元素设置且不可继承,动态dom须手动触发翻译,语言包须扁平结构并设fallback。

data-i18n 标记必须覆盖所有可翻译属性,不只是 textContent
只给 <button>Submit</button> 加 data-i18n="btn_submit",页面切换语言后,placeholder、alt、title 还是英文——这不是漏翻译,是根本没声明要翻译它们。
-
data-i18n只影响元素自身的textContent;placeholder、alt、title、aria-label等需显式加对应后缀:data-i18n-placeholder、data-i18n-alt、data-i18n-title -
value属性一般不翻译(属于用户输入数据),但<button type="submit"></button>和<input type="submit">的显示文案建议统一用textContent更新,避免提交时意外发错值 -
<label for="email">Email</label>翻译后,for属性必须与目标id严格一致,否则点击 label 失效 - 别在
<script></script>、<style></style>、<pre class="brush:php;toolbar:false;"></pre>里加data-i18n——这些节点不渲染为可见文本,JS 替换无效
lang 属性必须逐个设置,不能靠 document.documentElement.lang 继承
设了 document.documentElement.lang = 'zh-Hans',但页面里所有 <p></p>、<h2></h2>、<footer></footer> 仍没写 lang,结果:屏幕阅读器读错语音、中文顿号按英文间距渲染、<pre class="brush:php;toolbar:false;" lang="bash"></pre> 被中文字体覆盖——浏览器根本不看根节点的 lang。
- 每个含文本的语义化标签(
<h1></h1>、<p></p>、<section></section>、<footer></footer>)都得显式写lang="zh-Hans",值必须符合 BCP 47(zh_CN或chinese会被忽略) - 已有明确语言意图的元素(如
<pre class="brush:php;toolbar:false;" lang="bash"></pre>、<code lang="sql">、<p lang="ja"></p>)切换主语言时,**保留原lang值**,这是合法混排,不是 bug -
<title></title>和<meta name="description">完全不继承的lang,必须单独设 -
<script></script>和<style></style>内部写lang没意义,不参与文本渲染
JSON 语言包必须扁平、对齐、带 fallback,加载失败不能留白
语言包里键名嵌套成 {"ui": {"header": {"title": "Home"}},或某语言缺了 "btn_submit" 字段,JS 查不到就留空——用户看到的不是“提交”,是一片空白。
- 每个语言一个文件:
./locales/zh-Hans.json、./locales/en-US.json、./locales/ja.json,内容全是顶层键值对,结构严格扁平 - 所有语言文件键名必须完全一致;某语言暂未翻译,也要保留键并设为空字符串:
"btn_submit": "" - 加载用
fetch('./locales/${lang}.json'),外层try/catch,内部检查response.ok和response.headers.get('content-type')?.includes('application/json') - fallback 顺序必须是:先试完整码(
zh-HK)→ 再截主语言(zh)→ 最后退到默认语言(en);服务器返回非application/jsonMIME 时,fetch可能静默失败
动态插入的 DOM 必须手动触发翻译,不会自动监听
AJAX 加载弹窗、分页表格新行、懒加载模块插入后,data-i18n 还是原始键名——DOM 插入和翻译是两件事,JS 不会自动扫描新节点。
- 弹窗打开后,立即调用翻译函数遍历其内部所有
data-i18n元素 - 表格每页用
fetch获取新<tr>,插入 <code><tbody> 后,立刻对其子元素执行翻译 <li>不要依赖 MutationObserver 自动监听——开销大、易漏、难调试;明确在插入后调用一次更可控</li> <li>含 HTML 结构的文案(如 <code>"请阅读@#@#@#@#@#@#@#@#@#@0")必须用innerHTML替换,且语言包对应值要是可信纯 HTML 片段(无用户输入、不执行 JS),否则有 XSS 风险
复杂点不在怎么写代码,而在每个
lang 属性是否显式、每个 data-i18n- 后缀是否补全、每次动态插入后是否真调用了翻译——少一处,无障碍、SEO、字体回退、标点渲染就可能出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











