fix: 组件改用 useLocale 直读自身 i18n 实例(修复嵌入时文案回退成 key)
useI18n({ useScope: 'global' }) 在嵌入时解析到宿主已安装的 i18n 实例,
而非本子项目实例 -> mobileGame.* 文案回退成 i18n key(显示 ID)。
改为 useLocale composable 直接读本模块级 i18n.global,无论是否 app.use() 都正确。
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
// 语言切换:嵌入时父项目经 :locale prop 传入当前语言,watch 同步到本实例;
|
||||
// 独立运行时由本组件内的语言开关 + loadLocaleAsync 自管。
|
||||
import { ref, watch, defineAsyncComponent } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from './composables/useLocale.js'
|
||||
import i18n, { loadLocaleAsync } from './i18n/index.js'
|
||||
import HeroSection from './components/HeroSection.vue'
|
||||
import ScreenshotCarousel from './components/ScreenshotCarousel.vue'
|
||||
@@ -28,7 +28,7 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
|
||||
const tabs = subTabs
|
||||
const activeTab = ref(defaultSubTab)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import { assets } from '../config.js'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import Tag from './ui/Tag.vue'
|
||||
import { heroMeta } from '../config.js'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import VersionTimeline from './VersionTimeline.vue'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import { leaderboard } from '../config.js'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
|
||||
const rows = ref([])
|
||||
const state = ref('loading') // loading | ok | error
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import { assets } from '../config.js'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
const images = assets.screenshots
|
||||
const current = ref(0)
|
||||
let timer = null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
|
||||
const props = defineProps({
|
||||
tabs: { type: Array, required: true }, // [{ id, labelKey }]
|
||||
@@ -7,7 +7,7 @@ const props = defineProps({
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import TeamCard from './TeamCard.vue'
|
||||
import Leaderboard from './Leaderboard.vue'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../composables/useLocale.js'
|
||||
import { versions, tracks } from '../data/versions.js'
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
|
||||
// 按 tracks 数组顺序分组(3D 最终形态在前);同一线内按 order 排序
|
||||
const grouped = computed(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useLocale } from '../../composables/useLocale.js'
|
||||
|
||||
// 可复用页面外壳 -- 统一页面的容器宽度、垂直节奏与标题。
|
||||
// Props:
|
||||
@@ -13,7 +13,7 @@ const props = defineProps({
|
||||
padded: { type: Boolean, default: true }
|
||||
})
|
||||
|
||||
const { t } = useI18n({ useScope: 'global' })
|
||||
const { t } = useLocale()
|
||||
const title = computed(() => (props.titleKey ? t(props.titleKey) : ''))
|
||||
</script>
|
||||
|
||||
|
||||
14
src/composables/useLocale.js
Normal file
14
src/composables/useLocale.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { computed } from 'vue'
|
||||
import i18n from '../i18n/index.js'
|
||||
|
||||
// ★ 子项目自有的语言辅助 composable。
|
||||
// 关键:直接读模块级 i18n 实例的 global composer,而非 useI18n() 注入。
|
||||
// 原因:useI18n({ useScope: 'global' }) 解析的是「当前运行 app 已安装的全局 i18n」,
|
||||
// 嵌入 mainPage 时那是父项目的实例(不含本子项目 mobileGame.* 文案)-> 文案回退成 key。
|
||||
// 改为直接引用本子项目实例的 .global,无论是否 app.use() 都拿到本子项目的 t。
|
||||
export function useLocale() {
|
||||
const { t, locale } = i18n.global
|
||||
const isZh = computed(() => locale.value === 'zh-CN')
|
||||
const pick = (obj) => (isZh.value ? obj.zh : obj.en)
|
||||
return { t, locale, isZh, pick }
|
||||
}
|
||||
Reference in New Issue
Block a user