Vue I18n在setup中翻译数组导致内容需额外操作才渲染的问题求解
问题分析与解决方案
这个问题我之前也碰到过,核心原因是你在组件初始化时直接把翻译结果赋值给了faqs数组——这些值是一次性计算的静态快照,不会随着语言切换自动更新,因为它们没有绑定到i18n的响应式依赖上。只有<h1>里的t('FAQ.title')能正常更新,是因为它直接写在模板里,Vue会自动追踪它的依赖,语言变化时重新渲染。
修复方案:用computed包裹FAQ数据
把faqs改成响应式的计算属性,这样每次语言切换时,计算属性会重新执行t()获取最新的翻译内容,模板也会自动同步更新。
修改后的代码如下:
<template> <div class="bg-white"> <h1 class="text-4xl font-semibold my-10 text-center capitalize text-black dark:text-white" > {{ t('FAQ.title') }} </h1> <div class="space-y-4 mx-auto my-4 max-w-screen-lg"> <details class="group" v-for="faq in faqs" :key="faq.question"> <summary class="flex items-center list-none text-left justify-between p-4 rounded-lg cursor-pointer" > <h5 class="font-medium text-black">{{ faq.question }}</h5> <svg class="flex-shrink-0 ml-1.5 w-5 h-5 transition duration-500 group-open:-rotate-180" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" > <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> </svg> </summary> <ul v-if="faq.list"> <li class="px-4 my-2 ml-4 leading-relaxed text-secondary" v-for="answer in faq.answer" :key="answer" > {{ answer }} </li> </ul> <p class="px-4 my-2 ml-4 leading-relaxed text-secondary" v-else> {{ faq.answer }} </p> </details> </div> </div> </template> <script lang="ts"> import { defineComponent, computed } from 'vue' // 引入computed import { useI18n } from 'vue-i18n' export default defineComponent({ name: 'FAQ', setup() { const { t } = useI18n() // 把faqs改成computed属性,响应语言变化 const faqs = computed(() => [ { question: t('FAQ.questions[0]'), answer: t('FAQ.answers.answer1') }, { question: t('FAQ.questions[1]'), answer: [ t('FAQ.answers.answer2[0]'), t('FAQ.answers.answer2[1]'), t('FAQ.answers.answer2[2]'), t('FAQ.answers.answer2[3]'), t('FAQ.answers.answer2[4]') ], list: true }, { question: t('FAQ.questions[2]'), answer: t('FAQ.answers.answer3') }, { question: t('FAQ.questions[3]'), answer: t('FAQ.answers.answer4') }, { question: t('FAQ.questions[4]'), answer: t('FAQ.answers.answer5') }, { question: t('FAQ.questions[5]'), answer: t('FAQ.answers.answer6') }, { question: t('FAQ.questions[6]'), answer: t('FAQ.answers.answer7') }, { question: t('FAQ.questions[7]'), answer: t('FAQ.answers.answer8') }, { question: t('FAQ.questions[8]'), answer: t('FAQ.answers.answer9') }, { question: t('FAQ.questions[9]'), answer: t('FAQ.answers.answer10') }, { question: t('FAQ.questions[10]'), answer: t('FAQ.answers.answer11') }, { question: t('FAQ.questions[11]'), answer: t('FAQ.answers.answer12') } ]) return { faqs, t } } }) </script>
为什么这样有效?
computed()会自动追踪内部用到的响应式依赖(这里就是i18n的locale和翻译函数t())- 当语言切换时,
t()的返回值会变化,computed属性会自动重新计算整个faqs数组 - 模板里的
v-for会感知到faqs的变化,自动重新渲染所有FAQ条目,不需要手动切换语言或跳转页面
内容的提问来源于stack exchange,提问作者Tomas Gil Amoedo




