Web Components
対応バージョン
🆕 9.2+
TIP
この章の完全な例コードはこちらにあります
Vue 3.2以降、公式ドキュメントで説明されているように、Web Componentsを使用することが可能です。
これにより、Vue I18n v9.2以降からWeb ComponentsにおけるVue I18nの利用が可能になります。
Web ComponentsでVue I18nを使用する際には、いくつかの点に注意する必要があります。
Web Componentsの準備:I18nインスタンスをホストする
Vue 3.2以降でサポートされるdefineCustomElementを使用することで、SFCで実装されたVueコンポーネントをWeb Componentsとして提供できます。これは、useI18nを使用して実装されたVueコンポーネントをi18nサポート付きのWeb Componentsとして提供できることを意味します。
ただし、提供されたWeb ComponentsはHTMLに直接挿入することはできません。createI18nによって作成されたi18nインスタンスをホストするために以下のWeb Componentsを準備する必要があります。
i18nインスタンスをホストするWeb Components:
<script setup lang="ts">
import { provide } from 'vue'
import { createI18n, I18nInjectionKey } from 'vue-i18n'
/**
* 他のWeb Componentsのためにホストするためのi18nインスタンスを作成
*/
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>上記のコードには以下の3つのポイントがあります。
createI18nを呼び出してi18nインスタンスを作成setup内で、createI18nによって作成されたi18nインスタンスをI18nInjectionKeyとともにprovideに指定- テンプレートには
slot要素のみが含まれる
scriptブロック内では、まずcreateI18nを使ってi18nインスタンスを初期化します。Vueアプリケーションでは、createI18nによって作成されたi18nインスタンスは、Vueアプリケーションapp.use(createAppによって生成された)に指定することで、Vueプラグインとして利用できます。Vue I18nをVueアプリケーションにインストールするには、app.useを使ってi18nインスタンスを登録する必要があります。
defineCustomElementを使用する場合、VueコンポーネントはVueアプリケーション側からは制御できなくなります。そのため、Vueアプリケーション内でWeb Components版のコンポーネントを実行しても、Vueアプリケーション側からapp.useを使ってcreateI18nによって作成されたi18nインスタンスをターゲットのWeb Componentsにアタッチすることはできません。
そのため、Web Componentsにi18nインスタンスをアタッチするために、setupでprovideを使用して、他のWeb Componentsにi18nインスタンスを公開します。これにより、useI18nでi18nを実装したWeb Componentsが、provideを実装したWeb Componentsによってホストされることで動作できるようになります。
次に、他のWeb Componentsをホストするためには、templateブロックでslot要素を使用することで可能です。
このホストされた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 componentにおけるVue I18n</h1>
<hello-i18n />
</i18n-host>
</template>これまでに説明した完全な例はこちらで確認できます。
制限事項
- Web Componentsを実装するために使用できるVue I18nはComposition APIのみです。
- Web Componentsを実装する際、
useI18nで実装されたVueコンポーネントを一緒にインポートして使用することはできません。これは、Vue.jsのWeb Componentsに対するProvide / Injectの制限によるものです。