Nuxt3 Ant-design-vue国际化,自定义主题

9,100次阅读
没有评论

共计 8275 个字符,预计需要花费 21 分钟才能阅读完成。

使用 Nuxt3 版本的一些感悟(”nuxt”: “^3.2.3″)

一些基本需要了解的例如

页面布局 layout 文件夹 和根目录下的 app.vue 文件

基于文件的路由目录 pages 文加载 路由嵌套 传参等

自定义的组件 components 文加载(使用时无需引入 如果想关闭可在 nuxt.config.ts 关闭)

// 如果你想关闭自动导入, 你可以将 imports.autoImport 设置为 false.

exportdefaultdefineNuxtConfig({
  imports: {autoImport: false}
})

可组合式 API Composables 文件夹 就是自定义一些自己的 hooks

Nuxt 内置了一些 如 useCookie、useRoute、useRouter、useState、useHead、useFetch、、、具体官网查看

middleware 中间件目录 像 Vue3 中我们做一些路由守卫 就可以在这里写

plugins 插件目录 使用的一些第三方组件可以在此处使用

目前项目中使用到的只有这些 具体的使用和描述还是以官网为准 只是自己的一些见解。。。

当前项目目前使用的插件如下

"dependencies": {
    "@ant-design/icons-vue": "^6.1.0",
    "@pinia/nuxt": "^0.4.7",
    "ant-design-vue": "^3.2.15",
    "less": "^4.1.3",
    "pinia": "^2.0.33",
    "sass": "^1.59.3",
    "vue-i18n": "^9.2.2"
}

1. 安装 ant-design-vue

Nuxt 中使用第三方组件库需要在根目录下创建 plugins 文件夹,并在文件夹中创建自己的插件名称(无需在 nuxt.config.ts 文件中引入 Nuxt2 需要手动引入)

如在 plugins 文件夹下创建 ant-design-vue.ts 文件 内容如下 可选择全局引入或者按需加载

// import Antd from ‘ant-design-vue’; 全局引入

import {Button,Layout} from'ant-design-vue';
exportdefaultdefineNuxtPlugin((nuxtApp) => {// nuxtApp.vueApp.use(Antd);  全局使用 
    nuxtApp.vueApp
    .use(Button)
    .use(Layout)
});

当引入完组件后 接下来引入样式 因为 antd 的样式使用了 Less 作为开发语言 所以这里我使用了 less 文件 需要下载 less

当然你也可以使用 css 样式文件 引入样式文件(需要注意的是在这里引入的样式文件会全局加载)

在 nuxt.config.ts 文件中

exportdefaultdefineNuxtConfig({
    css:[
        // 'ant-design-vue/dist/antd.min.css',
        'ant-design-vue/dist/antd.less',
        '@/assets/css/animate.min.css',
      ],
})

现在在页面中就可以使用组件了


2. 使用 vue-i18n 首先安装

同样像使用 ant-design-vue 一样需要在 plugins 文件夹中注册

根目录下创建 locales 文件夹

locales
 | - lang
 | --- ZH      // 中文语言文件夹 在里面可以创建其他文件夹或者文件   我自己喜欢以路由为文件夹创建
 | ----- app.ts
 | --- zh.ts   //  在这里引入上面中文里面 ZH 文件夹中所有的定义   同理下面 EN 文件夹也是如何  如果有第三个语言 也可以如此创建
 | --- EN
 | ----- app.ts
 | --- en.ts
 | - index.ts  引入文件 zh.ts en.ts  并且导出

以上面的中文为例

locales/lang/zh.ts

importappfrom'./ZH/app'
importpaymentfrom'./ZH/payment'// 这里是我创建的一个文件夹  里面有一个 index.ts 文件 
​
exportdefault {
  ...app,
  ...payment
}

locales/lang/ZH/app.ts

exportdefault {app:{// 自定义  例如 上面的 payment 文件夹的 index  这里就可以使用文件夹的名称 payment:{}  避免重复
    title:'标题',
    auth:'该页面需要登录请登录后重试'
  }
}

locales/index.ts

importzhLocalefrom'./lang/zh'; // 引入本地语言  locales/lang/zh.ts
importenLocalefrom'./lang/en'
let zh= {...zhLocale,}
let en= {...enLocale,}
export {zh,en}// 导出

plugins 文件夹中创建 vue-i18n.ts 文件

import {createI18n} from'vue-i18n';
import {zh,en} from'@/locales/index';// 本地语言库
constmessage= {
  zh,
  en,
}
exportdefaultdefineNuxtPlugin((nuxtApp) => {constCookie=useCookie('lang');  
   // 这里使用了内置 api  可以快速设置获取 cookie   当然这里也可以设置在 localStorage 中使用 不使用 useCookie
  Cookie.value=Cookie.value||'zh'
  consti18n=createI18n({
    legacy:false,// 使用 vue3 组合式 API 时必须设置为 FALSE
    locale:Cookie.value||'zh',
    fallbackLocale: 'zh', // set fallback locale
    messages:message,
    globalInjection:true,// 全局注入 $t 函数
  })
  nuxtApp.vueApp.use(i18n)
});

接下来是语言切换

可以在任意的页面或者组建中进行语言的切换



  import {useI18n} from'vue-i18n';
  const {locale:renameLocale} =useI18n();
    
  constcurrentLang=useCookie('lang');// 获取 cookie 中的 lang
  constswitchLang= (val:string)=>{
    renameLocale.value=val;// 本地使用的语言
    currentLang.value=val;// 更改 cookie 中的值
  } 

当完成以上的配置后 就可以在页面中使用了

使用的方法有两种 在页面中使用 和 在 JS 中使用。



  import {useI18n} from'vue-i18n';
  const {t}  =useI18n();
  console.log(t('app.title'))// 标题

此时基本的操作就已经完成了 但是我们需要在页面初始化的时候就要确认使用的语言

然后结合 ant-design-vue 组件库国际化 按照官方文档配置

ant-design-vue 提供了一个 Vue 组件 ConfigProvider 用于全局配置国际化文案

在根目录下的 app.vue 文件中 当然别忘了 plugins/ant-design-vue.ts 文件中引入该组价



importzhfrom'ant-design-vue/es/locale/zh_CN';
importenfrom'ant-design-vue/es/locale/en_US';
importdayjsfrom'dayjs'; 
// ConfigProvider 不包含时间类组件的国际化,你需要额外引入时间库 (dayjs、momentjs、date-fns 等) 的国际化文件
import'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');
constcurrentLang=ref(en) ;//zh  en 

但是这时候我们的 antdesignvue 不会随着我们切换语言而改变 因为切换按钮不在当前的 app.vue 文件内 如果在相同的页面的话现在可以创建响应性的数据 currentLang 直接使用,,但是真是的项目中切换语言的按钮往往只是一个单纯的切换不和其他的组件在一起

当我们点击切换按钮的时候 更改本地语言 并且更改 cookie 中的 lang 字段 此时 app.vue 如果能实时监控获取更改后的值 然后就可以改变 currentLang 的值

这里我是用的是 pinia 像 vuex 一样 pinia 的数据也是响应性的

首先安装 pinia @pinia/nuxt

根目录下创建文件夹 store 我这里创建了两个模块 方便以后数据的存储

store
 | - modules
 | --- app.ts
 | --- user.ts
 | - index.ts 

store/index.ts

import {userStore} from'./modules/user';
import {appStore} from'./modules/app'
exportconstuseStore= ()=>({userStore:userStore(),
  appStore:appStore()})

store/modules/app.ts

import {defineStore} from'pinia';
// defineStore 方法有两个参数,第一个参数是模块化名字
// 第二个参数是选项,对象里面有三个属性,相比于 vuex 少了一个 mutations.
exportconstappStore=defineStore('app', {state(){  // 存放的就是模块的变量
    return {lang:useCookie('lang') ||'zh',
    }
  },
  getters:{getStateLang(state){// 页面中使用了多次,这里只会执行一次,然后缓存起来
      returnstate.lang?state.lang:'zh'
    },
  },
  actions:{changeLang(lang:string) {this.lang=lang;},
  }
})

接下来更改 app.vue 中的代码

我们需要首次获取到当前本地 cookie 中的值 如果 store 获取不到默认 zh



importzhfrom'ant-design-vue/es/locale/zh_CN';
importenfrom'ant-design-vue/es/locale/en_US';
importdayjsfrom'dayjs';
    
import {useStore} from'@/store'
import {storeToRefs} from'pinia'
conststore=useStore();
    
// 首次加载获取 默认 zh
constcurrentLang=ref(switchLangFun(store.appStore.getStateLang))
// 国际化时间组件
watch(currentLang, val=> {dayjs.locale(val.locale);
});
    
// 获取 store 中的语言  storeToRefs 可以创建一个响应式的数据   具体使用方法还是需要官方文档
const {lang} =storeToRefs(store.appStore);
watch(lang,val=>{if(val) currentLang.value=switchLangFun(val)
})
// 本地 cookie 中的 zh 是字符串
functionswitchLangFun(val:string){switch(val){
    case'zh':
      returnzh
    case'en':
      returnen
    case'hk':
      returnhk
    case'ar':
      returnar
    default:
      returnzh
  }
}  

到这里还有一个操作不要忘记 就是当我们点击切换的时候还要更改 store 中的 lang 的值

更改你刚才切换语言的组件



  import {useI18n} from'vue-i18n';
  const {locale:renameLocale} =useI18n();
    
  constcurrentLang=useCookie('lang');// 获取 cookie 中的 lang
  constswitchLang= (val:string)=>{
    renameLocale.value=val;// 本地使用的语言
    currentLang.value=val;// 更改 cookie 中的值
      
      
    // 改变 store
  store.appStore.changeLang(val)  ///changeLang 为 store 中的 actions 方法
  } 

至此这个项目中使用 vue-i18n 已经完成。。。。。。。

但是、、、、当我感觉一切都完成的时候 此时又发现一个问题

因为在 vue 的项目中难免会遇到路由守卫

通过对 Nuxt 的了解我们知道在 Nuxt 的项目中我们可以在 middleware 中间件中使用路由守卫。直接在 middleware 文件夹下创建文件即可。这里有全局的中间件和作用于文件的中间件 如何使用以官网为准

创建 auth.global.ts 文件 含有.global 的文件即为全局中间件 创建这个中间件主要对页面需要 token 的页面进行拦截 如果不存在 token 则重定向 login 登录或者提示信息(即使这个中间件不提示信息只做重定向 但是肯定会有别的中间件会提示信息进行拦截 比如某个页面需要一定的管理员权限才能进去 此时就不能重定向某个页面 只能提示然后终止导航)

auth.global.ts

import {messageasMessage,Modal} from'ant-design-vue'
import {useI18n} from'vue-i18n';
exportdefaultdefineNuxtRouteMiddleware((to, from) => {if(process.client){// 只在客户端显示   具体请以官网为准
    const {t}  =useI18n();
    consttoken=useCookie('app-token');
    // 某些特定的页面不需要 token  login register  reset  
    constnoTokenPath= ['/login','/register','/reset']
    if(!noTokenPath.includes(to.path)){if(!token.value){// Message.error('This is an error message');
        // return abortNavigation('500')
        Modal.error({
          title: 'Tip',
          content: t('app.auth'),// 该页面需要登录请登录后重试
        });
      }
    }
  }
​
})

因为提示的信息 肯定也是国际化的 按照正常的操作引入

import {useI18n} from ‘vue-i18n’;const {t} = useI18n();

但是当我们使用 t(‘app.auth’) 系统就会报错 Must be called at the top of a setup function 因为 vue-i18n 必须在 setup 中使用。

这时候我们需要 plugins 插件的帮助

更改 plugins/vue-i18n.ts 文件

import {createI18n} from'vue-i18n';
import {zh,en} from'@/locales/index';// 本地语言库
constmessage= {
  zh,
  en,
}
exportdefaultdefineNuxtPlugin((nuxtApp) => {constCookie=useCookie('lang');  
   // 这里使用了内置 api  可以快速设置获取 cookie   当然这里也可以设置在 localStorage 中使用 不使用 useCookie
  Cookie.value=Cookie.value||'zh'
  consti18n=createI18n({
    legacy:false,// 使用 vue3 组合式 API 时必须设置为 FALSE
    locale:Cookie.value||'zh',
    fallbackLocale: 'zh', // set fallback locale
    messages:message,
    globalInjection:true,// 全局注入 $t 函数
  })
  nuxtApp.vueApp.use(i18n)
   // 新增的  提供一个辅助函数    然后在中间件 auth.global.ts 中调用
  return{
    provide:{myi18n:()=>i18n
    }
  }
});

更改 middleware/auth.global.ts

import {messageasMessage,Modal} from'ant-design-vue'
//import {useI18n} from 'vue-i18n';
exportdefaultdefineNuxtRouteMiddleware((to, from) => {
   
   /// 新增的
  const {$myi18n} =useNuxtApp()
  const {t} =$myi18n().global
    
  if(process.client){// 只在客户端显示   具体请以官网为准
    //const {t}  = useI18n();
    consttoken=useCookie('app-token');
    // 某些特定的页面不需要 token  login register  reset  
    constnoTokenPath= ['/login','/register','/reset']
    if(!noTokenPath.includes(to.path)){if(!token.value){// Message.error('This is an error message');
        // return abortNavigation('500')
        Modal.error({
          title: 'Tip',
          content: t('app.auth'),// 该页面需要登录请登录后重试
        });
      }
    }
  }
​
})

nuxt.config.ts 中别忘了添加去除 vue-i18n 控制台警告

exportdefaultdefineNuxtConfig({
    ...
    vite:{
        ...
        resolve:{
          alias:{'vue-i18n':'vue-i18n/dist/vue-i18n.cjs.js'}
        }
        ...
    }
    ...
})

至此 vue-i18n 的使用基本已经完成,本地测试没有问题,打包本地测试也没有问题。end。。。。。。。。。。。。。

在 Nuxt3 中结合 Ant-design-vue 如何自定义主题。

这个问题我网上找了好多天的资料 都没有解决 最终在结合之前的 vue3 项目才解决掉,原本的出发点就不正确 一直以为解决的出发点应该在 nuxt 中解决 最终解决的方法在 Vite 插件配置中解决。需要安装插件 vite-plugin-style-import yarn add vite-plugin-style-import -D

import {createStyleImportPlugin,AntdResolve} from'vite-plugin-style-import'
exportdefaultdefineNuxtConfig({
    ...
    vite:{
        plugins:[
          createStyleImportPlugin({resolves: [AntdResolve()],
          }),
        ],
        css:{
            preprocessorOptions: {
                less: {
                  modifyVars: {// 更改主题
                    // hack: `true; @import (reference) "${path.resolve('src/assets/less/global.less')}";`,
                    'primary-color': '#2096f3', // 全局主色
                    'link-color': '#2096f3', // 链接色
                    'success-color': '#00B86B', // 成功色
                    'warning-color': '#FF9500', // 警告色
                  },
                  javascriptEnabled: true,
                },
              },
        }
    }
    ...
})

原文地址: Nuxt3 Ant-design-vue 国际化, 自定义主题

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-27发表,共计8275字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)