nuxt2 国际化i18n使用,语言切换

目标实现:
1.语言切换
2.路由切换

nuxt.config.js 
export default = {
  modules: [
        "@nuxtjs/i18n",
    ],
  i18n: {
        langDir: "locales/", // 本地语言配置目录
        locales: [
            {
                code: "en",
                iso: "en",
                name: 'English',
                file: "en.json",
            },
            {
                code: "cn",
                iso: "cn",
                name: '简体中文',
                file: "cn.json",
            },
            {
                code: "tw",
                iso: "tw",
                name: '繁体中文',
                file: "tw.json",
            },
        ],
        lazy: false,
        strategy: "prefix_and_default", // 路由策略,可选值有 prefix_except_default, prefix_and_default, prefix, no_prefix 等
        defaultLocale: 'en', // 直接设置默认语言代码
        vueI18n: {
            fallbackLocale: 'en',
            messages: {} // 动态加载语言文件时可以留空
        },
        detectBrowserLanguage: {
            useCookie: true,
            cookieKey: 'language',
            onlyOnRoot: true, // 这意味着只在用户首次访问应用的根路径时进行语言重定向
        },
        // router: { // 自定义路由规则 添加前缀,但保持自定义路由结构
        //     path: '{{$locale}}/_custom_path', // 注意:对于完全自定义的路由,你可能需要根据实际情况调整这部分配置
        //     prefix: '{{$locale}}' // 或者如果所有路由都应该是 /lang/path 这样的形式,则可以简化为
        // }
        // 配置未生效使用其他方式实现
    },
}

router.js 主要部分代码
const languages = ['en', 'cn', 'tw']; // 示例语言数组,根据实际情况调整
// 动态语言生成路由
function generateLocalizedRoutes(routesBase) {
  return languages.flatMap(lang => {
    return routesBase.map(route => {
      const localizedRoute = { ...route };
    //   if (localizedRoute.path !== '/') {
        localizedRoute.path = `/${lang}${localizedRoute.path}`;
    //   }
      return localizedRoute;
    });
  });
}
// 添加多语言的路由配置合并路由
routes = routes.concat(generateLocalizedRoutes(routes))
console.log(routes)

// 添加一个组件进行测试

<template>
    <div class="pl-15">
        <el-select
            v-model="lang"
            placeholder="Select"
            size="mini"
            style="width: 100px"
        >
            <el-option
                v-for="item in locales"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
        </el-select>
    </div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
    data() {
        return {
            lang: "en",
            locales: [
                {
                    value: "en",
                    label: "英文",
                },
                {
                    value: "cn",
                    label: "中文简体",
                },
                {
                    value: "tw",
                    label: "中文繁体",
                },
            ],
        };
    },
    watch: {
        lang(newLang) {
            this.changeLanguage(newLang);

            // 获取当前路径去除语言前缀
            let pathWithoutLang = this.$route.path;
            const langKeys = this.locales.map((item) => item.value);

            // 如果当前路径以支持的语言开始,则去除该前缀
            if (
                langKeys.some((lang) => pathWithoutLang.startsWith(`/${lang}`))
            ) {
                const langIndex = pathWithoutLang.indexOf("/", 1); // 找到第一个斜杠后的索引
                pathWithoutLang =
                    langIndex > 0 ? pathWithoutLang.substring(langIndex) : "";
            }

            // 构建新路径并导航
            const newPath = `/${newLang}${
                pathWithoutLang.startsWith("/") ? "" : "/"
            }${pathWithoutLang}`;
            this.$router.replace(newPath).catch((error) => {
                if (error.name !== "NavigationDuplicated") throw error; // 非重复导航错误重新抛出
            });
        },
    },
    created() {
        this.lang = this.$cookies.get("language") || "en";
    },
    methods: {
        ...mapMutations(["setLanguage"]),
        changeLanguage(newLanguage) {
            // 这里可以直接调用从 mutation 映射过来的方法
            this.setLanguage(newLanguage);
        },
        hasCommonItem(arr1, arr2) {
            const set = new Set(arr1);
            return arr2.some((item) => set.has(item));
        },
    },
};
</script>

实现效果:
路由携带语言,切换语言对应全局存储语言变量修改,cookie缓存修改

posted @ 2024-06-24 15:50  hello蔚蓝  阅读(820)  评论(1)    收藏  举报