Web 组件
支持的版本
🆕 9.2+
TIP
本章的完整示例代码在这里
Vue 3.2 及以后,我们可以像官方文档中描述的那样使用 WebComponents。
这将支持从 Vue I18n v9.2 开始在 Web Components 中使用 Vue I18n。
在将 Vue I18n 与 Web Components 一起使用时需要注意几点。
为托管 i18n 实例准备 Web Components
从 Vue 3.2 开始支持的 defineCustomElement,我们可以将使用 SFC 实现的 Vue 组件提供为 Web Components。这意味着使用 useI18n 实现的 Vue 组件可以作为带有 i18n 支持的 Web Components 提供。
然而,提供的 Web Components 不能直接插入 HTML 中。您需要准备以下 Web Components 来托管由 createI18n 创建的 i18n 实例。
托管 i18n 实例的 Web Components:
<script setup lang="ts">
import { provide } from 'vue'
import { createI18n, I18nInjectionKey } from 'vue-i18n'
/**
* 创建一个 i18n 实例以供其他 Web Components 托管
*/
const i18n = createI18n<false>({
legacy: false, // 必须设置为 `false`
locale: 'en',
messages: {
en: {
hello: 'Hello!'
},
ja: {
hello: 'こんにちは!'
}
}
})
/**
* 使用 `I18nInjectionKey` 为其他 Web Components 提供 i18n 实例
*/
provide(I18nInjectionKey, i18n)
</script>
<!-- 模板用于插入内容 -->
<template>
<slot />
</template>上述代码有以下三点:
- 调用
createI18n创建 i18n 实例 - 在
setup中,将使用createI18n创建的 i18n 实例连同I18nInjectionKey一并传给provide - 模板只包含
slot元素
在 script 块中,我们首先使用 createI18n 创建 i18n 实例。在 Vue 应用程序中,通过在通过 createApp 创建的 Vue 应用程序 app.use 中指定 i18n 实例,可以将 createI18n 创建的 i18n 实例用作 Vue 插件。我们需要将 Vue I18n 安装为 Vue 应用程序的 Vue 插件。
如果使用 defineCustomElement,Vue 组件将不能再从 Vue 应用程序端控制,因此即使在您的 Vue 应用程序中运行 Web Components 版本的组件,也无法通过从 Vue 应用程序端的 app.use 将使用 createI18n 创建的 i18n 实例附加到目标 Web Components。
因此,为了将 i18n 实例附加到 Web Components,我们在 setup 中使用 provide 将 i18n 实例暴露给其他 Web Components。这使得使用 useI18n 实现 i18n 的 Web Components 可以通过托管 provide 的 Web Components 工作。
然后,为了托管其他 Web Components,通过使用 slot 元素就可以实现 template 块。
按以下方式导出托管的 Web Components:
import { defineCustomElement } from 'vue'
import I18nHost from './components/I18nHost.ce.vue'
const I18nHostElement = defineCustomElement(I18nHost)
export { I18nHostElement }以下 useI18n 实现并导出 Web Components:
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
<template>
<p>{{ t('hello') }}</p>
</template>import { defineCustomElement } from 'vue'
import HelloI18n from './components/HelloI18n.ce.vue'
const HelloI18nElement = defineCustomElement(HelloI18n)
export { HelloI18nElement }当以下 Vue 应用程序注册为 Web Components 的自定义元素时:
import { createApp } from 'vue'
import { I18nHostElement } from './path/to/I18nHostElement'
import { HelloI18nElement } from './path/to/HelloI18nElement'
import App from './App.vue'
customElements.define('i18n-host', I18nHostElement)
customElements.define('hello-i18n', HelloI18nElement)
createApp(App).mount('#app')所以,在 Vue 应用程序的入口点 App.vue 中,以下模板将能正常工作:
<template>
<i18n-host>
<h1>Web 组件中的 Vue I18n</h1>
<hello-i18n />
</i18n-host>
</template>到目前为止描述的完整示例可以在这里查看。
限制
- 用于实现 Web Components 的 Vue I18n 只有 组合式 API。
- 实现 Web Components 时,不能同时导入和使用使用
useI18n实现的 Vue 组件。这是由于 Vue.js 的 Web Components 对 Provide / Inject 的限制。