Provide 是 Vue 3 跨层级传递 i18n 实例的核心机制,通过 app.provide 注入 reactive 的 locale/messages/t 函数,后代组件用 inject 安全获取并自动响应语言切换。

Provide 是 Vue 3 中用于跨层级组件传递依赖的核心机制,i18n 插件正是借助它实现语言状态与翻译函数的全局可访问性——不靠 props 层层透传,也不依赖全局变量,而是把 i18n 实例“提供”给整个应用树。
Provide 如何承载 i18n 实例
插件在 install 方法中调用 app.provide,将封装好的 i18n 对象(含 locale、messages、t 函数等)注入应用上下文。这个对象会被所有后代组件通过 inject 拿到,且天然响应式——只要 locale 或 messages 变更,依赖它的组件就会自动更新。
- i18n 实例通常包含 reactive 的
locale和messages,确保语言切换触发视图重渲染 - 提供的 key 建议使用 Symbol 避免命名冲突,例如
const I18N_SYMBOL = Symbol('i18n') - provide 的值可以是 ref、reactive 或普通对象,但推荐用 reactive 包裹核心状态,便于后续 inject 后直接解构使用
inject 在组件中安全获取翻译能力
任意组件(包括函数式组件或组合式 API 中的 setup)都能用 inject(I18N_SYMBOL) 拿到 i18n 实例。为避免未 provide 时出错,建议设默认值或配合 getCurrentInstance 做容错。
- 常用写法:
const i18n = inject(I18N_SYMBOL, null),后续加非空判断 - 可在 composable 中封装:如
useI18n()内部统一 inject 并返回t和locale,提升复用性 - 模板中仍可配合
v-t指令或{{ $t('key') }}语法糖(需在 app.config.globalProperties 上挂载,属于补充方案,非 provide 必需)
响应式切换语言的关键细节
语言切换不是简单赋值,必须保证响应链完整。provide 的对象本身不自动响应,关键在于内部状态是否被 reactive 包裹。
- 错误做法:直接
i18n.locale = 'zh'(若 locale 是普通属性,则不会触发更新) - 正确做法:locale 定义为
ref('en')或放在 reactive 对象里,切换时改i18n.locale.value = 'zh'或i18n.state.locale = 'zh' - 翻译函数
t(key)应读取当前 locale 和 messages,内部用unref处理响应式数据,确保 key 变化时重新计算
插件结构与实战注入示例
一个最小可用 i18n 插件只需三部分:create 函数创建实例、install 方法 provide、以及配套的 useI18n 工具函数。
- createI18n 接收配置(locale、messages),返回 reactive 对象:
{ locale, messages, t: (key) => {...} } - install 中:
app.provide(I18N_SYMBOL, i18n),同时可选地app.config.globalProperties.$t = i18n.t - 在 main.ts 中:先
const i18n = createI18n({...}),再app.use(i18n),即可全局生效

















