用 computed 实现国际化需确保 locale 为响应式并被翻译函数直接读取,如 const submitText = computed(() => t('button.submit'));避免非响应式赋值和模板中重复调用 t()。

用 computed 实现国际化文本实时切换,核心在于把语言标识(如 locale)作为响应式依赖,让翻译函数自动重计算。只要语言状态一变,所有绑定的文本立刻更新,无需手动刷新或重新渲染组件。
语言状态必须是响应式的
Vue 的 computed 能自动追踪依赖,前提是语言字段本身是响应式的。推荐用 ref 或 reactive 管理当前语言:
- 使用
const locale = ref('zh'),后续通过locale.value = 'en'切换 - 若放在 store 中(如 Pinia),确保该字段是
state的响应式属性,而非普通对象字段 - 避免直接赋值非响应式变量(例如
let lang = 'zh'; lang = 'en'),这样 computed 不会触发更新
翻译函数要封装成纯函数并依赖 locale
定义一个接收 key 和当前 locale 的翻译函数,内部查表返回对应文案。关键点是:这个函数必须在 computed 内调用,且 locale 必须被访问到:
- 不要写成
computed(() => t('button.submit'))并在外部传 locale —— locale 没出现在函数体内,无法建立依赖 - computed(() => t('button.submit', locale.value)),或更常见的是把 locale 提前解构:
const { t } = useI18n(); computed(() => t('button.submit'))(前提是useI18n内部已将 locale 响应式接入) - 翻译表建议按语言拆分成对象,例如
{ zh: { 'button.submit': '提交' }, en: { 'button.submit': 'Submit' } }
避免在模板中重复调用 t(),优先用 computed 封装文案
模板里每写一次 {{ t('xxx') }},就会创建一个独立的 computed 依赖链。高频更新或大量文案时影响性能。更优做法是提前在 script 中声明:
const submitText = computed(() => t('button.submit'))const pageTitle = computed(() => t('page.home.title'))- 模板中直接用
{{ submitText }}—— 语义清晰、复用方便、依赖集中
注意异步加载语言包时的响应式衔接
如果语言包是动态 import 的(比如按需加载 en.json),需确保加载完成后再更新 locale,并让翻译函数能处理空值或 fallback:
- 初始 locale 可设为
ref(null),加载完再赋值真实值,避免渲染时报错 - 翻译函数内加判断:
if (!messages[locale]?.[key]) return key,防止白屏或显示 undefined - 配合
watch监听 locale 变化并触发 loadLocaleMessages(locale.value),但记得在 load 完成后才更新实际使用的 messages 对象
不复杂但容易忽略:computed 的响应性只认“读取”,不认“传参”。只要 locale 在函数体里被真正访问过,切换时就能精准更新。

















