这篇内容是在有道云旧笔记基础上重新整理的 Vue/Vite 工程实践 笔记。原始记录偏碎片化,这里补充了使用场景、阅读顺序和落地时需要注意的边界,方便以后在项目里快速复用。
适用场景
- Vue/Vite 项目中遇到配置、组件封装、构建或运行时问题时,作为排查入口。
- 需要把一次性调试经验沉淀成团队内可复用的前端工程实践。
- 迁移旧项目或升级依赖时,用来对照检查环境变量、插件和组件行为差异。
核心要点
- 正文以代码或命令片段为主,阅读时建议先确认目标问题,再挑选对应片段验证。
- 保留了 3 段可直接参考的代码或命令,主要涉及 javascript,复制前需要按当前项目路径、版本和变量名做调整。
- 涉及命令行操作时,建议先在测试目录或测试环境执行,确认输出符合预期后再应用到生产环境。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| loader.js
const dayjsLocales = import.meta.glob('../../node_modules/dayjs/locale/*.js');
const vantLocales = import.meta.glob('../../node_modules/vant/es/locale/lang/*.mjs');
export default async function loadLocale(lang) { const lowerCase = lang.toLowerCase(); const dayjsKey = `../../node_modules/dayjs/locale/${lowerCase}.js`; const vantKey = `../../node_modules/vant/es/locale/lang/${lang}.mjs`;
if (dayjsLocales[dayjsKey]) { const dayjs = (await import('dayjs')).default; dayjs.locale(lowerCase); } else { console.warn(`Day.js: Missing locale for ${lang}`); }
if (vantLocales[vantKey]) { const mod = await vantLocales[vantKey](); const { Locale } = await import('vant'); Locale.use(lang, mod.default); } else { console.warn(`Vant: Missing locale for ${lang}`); } }
import loadLocale from './loader'; export function setHtmlPageLang(locale) { loadLocale(locale); const html = document.querySelector('html'); if (html && html.getAttribute('lang') !== locale) { html.setAttribute('lang', locale); } }
import messages from '@intlify/unplugin-vue-i18n/messages'; import { createI18n } from 'vue-i18n'; import Locales from '../../locales.config'; import loadLocale from './loader';
let i18n;
function createI18nOptions() { const locale = navigator?.language || 'zh-CN'; const i18nOptions = { locale, legacy: false, fallbackLocale: 'zh-CN', availableLocales: [...Locales], messages: {}, };
if (locale) { setHtmlPageLang(locale); i18nOptions.messages = messages; }
return i18nOptions; }
export default function initI18n(app) { const options = createI18nOptions();
i18n = createI18n(options); app.use(i18n); }
export function setHtmlPageLang(locale) { loadLocale(locale); const html = document.querySelector('html'); if (html && html.getAttribute('lang') !== locale) { html.setAttribute('lang', locale); } }
export function changeLanguage(locale) { i18n.global.locale = locale; setHtmlPageLang(locale); }
|
手动导入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| import messages from '@intlify/unplugin-vue-i18n/messages'; import { createI18n } from 'vue-i18n'; import Locales from '../../locales.config'; import loadDayjs from './dayjs'; import loadVant from './vant';
let i18n;
function createI18nOptions() { const locale = navigator?.language || 'zh-CN'; const i18nOptions = { locale, legacy: false, fallbackLocale: 'zh-CN', availableLocales: [...Locales], messages: {}, };
if (locale) { setHtmlPageLang(locale); i18nOptions.messages = messages; }
return i18nOptions; }
export default function initI18n(app) { const options = createI18nOptions(); i18n = createI18n(options); app.use(i18n); }
export function setHtmlPageLang(locale) { loadDayjs(locale); loadVant(locale); const html = document.querySelector('html'); if (html && html.getAttribute('lang') !== locale) { html.setAttribute('lang', locale); } }
export function changeLanguage(locale) { i18n.global.locale.value = locale; setHtmlPageLang(locale); }
import dayjs from 'dayjs'; import localesConfig from '../../locales.config';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/en';
const localeMap = { 'zh-CN': 'zh-cn', 'en-US': 'en', };
const usableLocales = Object.fromEntries( Object.entries(localeMap).filter(([key]) => localesConfig.includes(key)) );
export default function loadDayjs(locale) { const dayjsLocale = usableLocales[locale]; if (dayjsLocale) dayjs.locale(dayjsLocale); }
import { Locale } from 'vant'; import localesConfig from '../../locales.config';
import enUS from 'vant/es/locale/lang/en-US'; import zhCN from 'vant/es/locale/lang/zh-CN';
const vantLocales = { 'zh-CN': zhCN, 'en-US': enUS, };
const usableLocales = Object.fromEntries( Object.entries(vantLocales).filter(([key]) => localesConfig.includes(key)) );
export default function loadVant(locale) { const vantLocale = usableLocales[locale]; if (vantLocale) Locale.use(locale, vantLocale); }
export default Object.freeze(['zh-CN', 'en-US']);
|
实践检查清单
- 先确认 Vue、Vite、Node、包管理器版本,再判断示例是否需要按当前工程结构调整。
- 涉及构建或插件配置时,建议同时验证开发环境和生产构建结果。
- 涉及 UI 或浏览器行为时,至少在桌面端和移动端各验证一次关键路径。
- 涉及接口、服务端或权限逻辑时,补充失败分支和权限边界测试。
复盘小结
这篇笔记更适合作为问题排查或方案落地前的速查材料。后续如果在真实项目中再次遇到同类问题,可以继续把具体版本、报错信息、最终取舍和验证结果补到对应小节里,让它从代码片段逐步沉淀成完整方案。
Author:蓝思同学
Permalink:https://www.lancema.com/posts/2025/vue/vite动态加载配置国际化.html
Slogan:small is beautiful, small is powerful !