vue3+ts项目04-国际化

yarn add vue-i18n
yarn add js-cookie
yarn add @types/js-cookie

src下新建i18n文件夹,该文件夹下新建lang和pages文件夹,
lang文件夹下新建en.ts

// 定义内容
export default {router: {home: 'home',system: {system: 'system',menu: 'systemMenu',role: 'systemRole',user: 'systemUser',dic: 'systemDic',city: 'systemDept'},personal: 'personal',},staticRoutes: {signIn: 'signIn',notFound: 'notFound',noPower: 'noPower',},user: {title0: 'Component size',title1: 'Language switching',title2: 'Menu search',title3: 'Layout configuration',title4: 'news',title5: 'Full screen on',title6: 'Full screen off',dropdownLarge: 'large',dropdownDefault: 'default',dropdownSmall: 'small',dropdown1: 'home page',dropdown2: 'Personal Center',dropdown3: '404',dropdown4: '401',dropdown5: 'Log out',dropdown6: 'Code warehouse',searchPlaceholder: 'Menu search: support Chinese, routing path',newTitle: 'notice',newBtn: 'All read',newGo: 'Go to the notification center',newDesc: 'No notice',logOutTitle: 'Tips',logOutMessage: 'This operation will log out. Do you want to continue?',logOutConfirm: 'determine',logOutCancel: 'cancel',logOutExit: 'Exiting',},tagsView: {refresh: 'refresh',close: 'close',closeOther: 'closeOther',closeAll: 'closeAll',fullscreen: 'fullscreen',closeFullscreen: 'closeFullscreen',},notFound: {foundTitle: 'Wrong address input, please re-enter the address~',foundMsg: 'You can check the web address first, and then re-enter or give us feedback.',foundBtn: 'Back to home page',},noAccess: {accessTitle: 'You are not authorized to operate~',accessMsg: 'Contact information: add QQ group discussion 665452019',accessBtn: 'Reauthorization',},layout: {configTitle: 'Layout configuration',oneTitle: 'Global Themes',twoTopTitle: 'top bar set up',twoMenuTitle: 'Menu set up',twoColumnsTitle: 'Columns set up',twoTopBar: 'Top bar background',twoTopBarColor: 'Top bar default font color',twoIsTopBarColorGradual: 'Top bar gradient',twoMenuBar: 'Menu background',twoMenuBarColor: 'Menu default font color',twoIsMenuBarColorGradual: 'Menu gradient',twoColumnsMenuBar: 'Column menu background',twoColumnsMenuBarColor: 'Default font color bar menu',twoIsColumnsMenuBarColorGradual: 'Column gradient',twoIsColumnsMenuHoverPreload: 'Column Menu Hover Preload',threeTitle: 'Interface settings',threeIsCollapse: 'Menu horizontal collapse',threeIsUniqueOpened: 'Menu accordion',threeIsFixedHeader: 'Fixed header',threeIsClassicSplitMenu: 'Classic layout split menu',threeIsLockScreen: 'Open the lock screen',threeLockScreenTime: 'screen locking(s/s)',fourTitle: 'Interface display',fourIsShowLogo: 'Sidebar logo',fourIsBreadcrumb: 'Open breadcrumb',fourIsBreadcrumbIcon: 'Open breadcrumb icon',fourIsTagsview: 'Open tagsview',fourIsTagsviewIcon: 'Open tagsview Icon',fourIsCacheTagsView: 'Enable tagsview cache',fourIsSortableTagsView: 'Enable tagsview drag',fourIsShareTagsView: 'Enable tagsview sharing',fourIsFooter: 'Open footer',fourIsGrayscale: 'Grey model',fourIsInvert: 'Color weak mode',fourIsDark: 'Dark Mode',fourIsWartermark: 'Turn on watermark',fourWartermarkText: 'Watermark copy',fiveTitle: 'Other settings',fiveTagsStyle: 'Tagsview style',fiveAnimation: 'page animation',fiveColumnsAsideStyle: 'Column style',fiveColumnsAsideLayout: 'Column layout',sixTitle: 'Layout switch',sixDefaults: 'One',sixClassic: 'Two',sixTransverse: 'Three',sixColumns: 'Four',tipText: 'Click the button below to copy the layout configuration to `/src/stores/themeConfig.ts` It has been modified in.',copyText: 'replication configuration',resetText: 'restore default',copyTextSuccess: 'Copy succeeded!',copyTextError: 'Copy failed!',},
};

lang文件夹下新建zh-cn.ts

// 定义内容
export default {router: {home: '首页',system: {system: '系统设置',menu: '菜单管理',role: '角色管理',user: '用户管理',dic: '字典管理',city: '城市管理'},personal: '个人中心',},staticRoutes: {signIn: '登录',notFound: '找不到此页面',noPower: '没有权限',},user: {title0: '组件大小',title1: '语言切换',title2: '菜单搜索',title3: '布局配置',title4: '消息',title5: '开全屏',title6: '关全屏',dropdownLarge: '大型',dropdownDefault: '默认',dropdownSmall: '小型',dropdown1: '首页',dropdown2: '个人中心',dropdown3: '404',dropdown4: '401',dropdown5: '退出登录',dropdown6: '代码仓库',searchPlaceholder: '菜单搜索:支持中文、路由路径',newTitle: '通知',newBtn: '全部已读',newGo: '前往通知中心',newDesc: '暂无通知',logOutTitle: '提示',logOutMessage: '此操作将退出登录, 是否继续?',logOutConfirm: '确定',logOutCancel: '取消',logOutExit: '退出中',},tagsView: {refresh: '刷新',close: '关闭',closeOther: '关闭其它',closeAll: '全部关闭',fullscreen: '当前页全屏',closeFullscreen: '关闭全屏',},notFound: {foundTitle: '地址输入错误,请重新输入地址~',foundMsg: '您可以先检查网址,然后重新输入或给我们反馈问题。',foundBtn: '返回首页',},noAccess: {accessTitle: '您未被授权,没有操作权限~',accessMsg: '联系方式:加QQ群探讨 665452019',accessBtn: '重新授权',},layout: {configTitle: '布局配置',oneTitle: '全局主题',twoTopTitle: '顶栏设置',twoMenuTitle: '菜单设置',twoColumnsTitle: '分栏设置',twoTopBar: '顶栏背景',twoTopBarColor: '顶栏默认字体颜色',twoIsTopBarColorGradual: '顶栏背景渐变',twoMenuBar: '菜单背景',twoMenuBarColor: '菜单默认字体颜色',twoIsMenuBarColorGradual: '菜单背景渐变',twoColumnsMenuBar: '分栏菜单背景',twoColumnsMenuBarColor: '分栏菜单默认字体颜色',twoIsColumnsMenuBarColorGradual: '分栏菜单背景渐变',twoIsColumnsMenuHoverPreload: '分栏菜单鼠标悬停预加载',threeTitle: '界面设置',threeIsCollapse: '菜单水平折叠',threeIsUniqueOpened: '菜单手风琴',threeIsFixedHeader: '固定 Header',threeIsClassicSplitMenu: '经典布局分割菜单',threeIsLockScreen: '开启锁屏',threeLockScreenTime: '自动锁屏(s/秒)',fourTitle: '界面显示',fourIsShowLogo: '侧边栏 Logo',fourIsBreadcrumb: '开启 Breadcrumb',fourIsBreadcrumbIcon: '开启 Breadcrumb 图标',fourIsTagsview: '开启 Tagsview',fourIsTagsviewIcon: '开启 Tagsview 图标',fourIsCacheTagsView: '开启 TagsView 缓存',fourIsSortableTagsView: '开启 TagsView 拖拽',fourIsShareTagsView: '开启 TagsView 共用',fourIsFooter: '开启 Footer',fourIsGrayscale: '灰色模式',fourIsInvert: '色弱模式',fourIsDark: '深色模式',fourIsWartermark: '开启水印',fourWartermarkText: '水印文案',fiveTitle: '其它设置',fiveTagsStyle: 'Tagsview 风格',fiveAnimation: '主页面切换动画',fiveColumnsAsideStyle: '分栏高亮风格',fiveColumnsAsideLayout: '分栏布局风格',sixTitle: '布局切换',sixDefaults: '默认',sixClassic: '经典',sixTransverse: '横向',sixColumns: '分栏',tipText: '点击下方按钮,复制布局配置去 `src/stores/themeConfig.ts` 中修改。',copyText: '一键复制配置',resetText: '一键恢复默认',copyTextSuccess: '复制成功!',copyTextError: '复制失败!',},
};

pages下新建login文件夹,该文件下新建en.ts和zh-cn.ts

// 定义内容
export default {label: {one1: 'User name login',two2: 'Mobile number',},link: {one3: 'Third party login',two4: 'Links',},account: {accountPlaceholder1: 'The user name admin or not is common',accountPlaceholder2: 'Password: 123456',accountPlaceholder3: 'Please enter the verification code',accountBtnText: 'Sign in',},mobile: {placeholder1: 'Please input mobile phone number',placeholder2: 'Please enter the verification code',codeText: 'Get code',btnText: 'Sign in',msgText:'Warm tip: it is recommended to use Google, Microsoft edge, version 79.0.1072.62 and above browsers, and 360 browser, please use speed mode',},scan: {text: 'Open the mobile phone to scan and quickly log in / register',},signInText: 'welcome back!',
};

zh-cn.ts

// 定义内容
export default {label: {one1: '用户名登录',two2: '手机号登录',},link: {one3: '第三方登录',two4: '友情链接',},account: {accountPlaceholder1: '用户名 admin 或不输均为 common',accountPlaceholder2: '密码:123456',accountPlaceholder3: '请输入验证码',accountBtnText: '登 录',},mobile: {placeholder1: '请输入手机号',placeholder2: '请输入验证码',codeText: '获取验证码',btnText: '登 录',msgText: '* 温馨提示:建议使用谷歌、Microsoft Edge,版本 79.0.1072.62 及以上浏览器,360浏览器请使用极速模式',},scan: {text: '打开手机扫一扫,快速登录/注册',},signInText: '欢迎回来!',
};

stores下interface下新建index.ts

//定义接口来定义对象的类型 `stores` 全部类型定义在这里/*** 用户信息*/
export interface UserInfosState {authBtnList: string[];photo: string;time: number;userName: string;roleId: number;
}
export interface UserInfosStates {userInfos: UserInfosState;
}/*** 路由缓存列表*/
export interface KeepAliveNamesState {keepAliveNames: string[];cachedViews: string[];
}/*** 后端返回原始路由(未处理时)*/
export interface RequestOldRoutesState {requestOldRoutes: string[];
}/*** TagsView 路由列表*/
export interface TagsViewRoutesState {tagsViewRoutes: string[];isTagsViewCurrenFull: Boolean;
}/*** 路由列表*/
export interface RoutesListState {routesList: string[];isColumnsMenuHover: Boolean;isColumnsNavHover: Boolean;
}/*** 布局配置*/
export interface ThemeConfigState {passwordKey: string;isDrawer: boolean;primary: string;topBar: string;topBarColor: string;isTopBarColorGradual: boolean;menuBar: string;menuBarColor: string;isMenuBarColorGradual: boolean;columnsMenuBar: string;columnsMenuBarColor: string;isColumnsMenuBarColorGradual: boolean;isColumnsMenuHoverPreload: boolean;isCollapse: boolean;isUniqueOpened: boolean;isFixedHeader: boolean;isFixedHeaderChange: boolean;isClassicSplitMenu: boolean;isLockScreen: boolean;lockScreenTime: number;isShowLogo: boolean;isShowLogoChange: boolean;isBreadcrumb: boolean;isTagsview: boolean;isBreadcrumbIcon: boolean;isTagsviewIcon: boolean;isCacheTagsView: boolean;isSortableTagsView: boolean;isShareTagsView: boolean;isFooter: boolean;isGrayscale: boolean;isInvert: boolean;isIsDark: boolean;isWartermark: boolean;wartermarkText: string;tagsStyle: string;animation: string;columnsAsideStyle: string;columnsAsideLayout: string;layout: string;isRequestRoutes: boolean;globalTitle: string;globalViceTitle: string;globalViceTitleMsg: string;globalI18n: string;globalComponentSize: string;
}/*** 布局配置*/
export interface ThemeConfigStates {themeConfig: ThemeConfigState;
}

stores下新建themeConfig.ts

import { defineStore } from 'pinia';
import { ThemeConfigStates, ThemeConfigState } from './interface';export const useThemeConfig = defineStore('themeConfig', {state: (): ThemeConfigStates => ({themeConfig: {//密码加密盐passwordKey: `4vRk^ga52xVP$B2vYK$%r8a8hctLgbU9`,isDrawer: false,primary: '#409eff',isIsDark: false,topBar: '#ffffff',topBarColor: '#606266',isTopBarColorGradual: false,menuBar: '#545c64',menuBarColor: '#eaeaea',isMenuBarColorGradual: false,columnsMenuBar: '#545c64',columnsMenuBarColor: '#e6e6e6',isColumnsMenuBarColorGradual: false,isColumnsMenuHoverPreload: false,isCollapse: false,isUniqueOpened: true,isFixedHeader: false,isFixedHeaderChange: false,isClassicSplitMenu: false,isLockScreen: false,lockScreenTime: 30,isShowLogo: true,isShowLogoChange: false,isBreadcrumb: true,isTagsview: true,isBreadcrumbIcon: true,isTagsviewIcon: true,isCacheTagsView: false,isSortableTagsView: true,isShareTagsView: false,isFooter: true,isGrayscale: false,isInvert: false,isWartermark: false,wartermarkText: 'vue-next-admin',tagsStyle: 'tags-style-five',animation: 'opacitys',columnsAsideStyle: 'columns-round',columnsAsideLayout: 'columns-vertical',layout: 'defaults',isRequestRoutes: true,globalTitle: '甜蜜蜜开放平台',globalViceTitle: '甜蜜蜜开放平台',globalViceTitleMsg: '专注、免费、开源、维护、解疑',globalI18n: 'zh-cn',globalComponentSize: 'large',},}),actions: {setThemeConfig(data: ThemeConfigState) {this.themeConfig = data;},},
});

i18n文件下新建index.ts

import { createI18n } from 'vue-i18n';
import pinia from '@/stores/index';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/stores/themeConfig';
import zhcnLocale from 'element-plus/es/locale/lang/zh-cn';
import enLocale from 'element-plus/es/locale/lang/en';import nextZhcn from '@/i18n/lang/zh-cn';
import nextEn from '@/i18n/lang/en';import pagesLoginZhcn from '@/i18n/pages/login/zh-cn';
import pagesLoginEn from '@/i18n/pages/login/en';// 定义语言国际化内容
/*** 说明:* /src/i18n/lang 下的 ts 为框架的国际化内容* /src/i18n/pages 下的 ts 为各页面的国际化内容*/
const messages = {[zhcnLocale.name]: {...zhcnLocale,message: {...nextZhcn,...pagesLoginZhcn,},},[enLocale.name]: {...enLocale,message: {...nextEn,...pagesLoginEn,},},
};// 读取 pinia 默认语言
const stores = useThemeConfig(pinia);
const { themeConfig } = storeToRefs(stores);// 导出语言国际化
//https://vue-i18n.intlify.dev/
// https://vue-i18n.intlify.dev/guide/essentials/fallback.html#explicit-fallback-with-one-locale
export const i18n = createI18n({//是否在您的 Vue 应用程序上使用 vue-i18n Legacy API 模式,默认使用 Legacy API 模式。如果要使用Composition API模式,需要将其设置为false。legacy: false,//是否抑制本地化失败时输出的警告。如果为 true,则抑制本地化失败警告。如果您使用正则表达式,则可以抑制与翻译键(例如 t)匹配的本地化失败警告。silentTranslationWarn: true,//丢失的警告missingWarn: false,//当您的语言缺少键的翻译时,是否对翻译键进行模板插值。如果为 true,则跳过为您的“基本”语言编写模板;key是你的模板。silentFallbackWarn: true,//失败时的警告fallbackWarn: false,//当前语言,本地化的语言环境locale: themeConfig.value.globalI18n,//都失败的情况下使用的语言,此 VueI18n 实例正在使用的当前后备区域设置。fallbackLocale: zhcnLocale.name,messages,
});

utils下新建storage.ts

import Cookies from 'js-cookie';/*** window.localStorage 浏览器永久缓存* @method set 设置永久缓存* @method get 获取永久缓存* @method remove 移除永久缓存* @method clear 移除全部永久缓存*/
export const Local = {// 设置永久缓存set(key: string, val: any) {window.localStorage.setItem(key, JSON.stringify(val));},// 获取永久缓存get(key: string) {const json: any = window.localStorage.getItem(key);return JSON.parse(json);},// 移除永久缓存remove(key: string) {window.localStorage.removeItem(key);},// 移除全部永久缓存clear() {window.localStorage.clear();},
};/*** window.sessionStorage 浏览器临时缓存* @method set 设置临时缓存* @method get 获取临时缓存* @method remove 移除临时缓存* @method clear 移除全部临时缓存*/
export const Session = {// 设置临时缓存set(key: string, val: any) {if (key === 'token') return Cookies.set(key, val);window.sessionStorage.setItem(key, JSON.stringify(val));},// 获取临时缓存get(key: string) {if (key === 'token') return Cookies.get(key);const json: any = window.sessionStorage.getItem(key);return JSON.parse(json);},// 移除临时缓存remove(key: string) {if (key === 'token') return Cookies.remove(key);window.sessionStorage.removeItem(key);},// 移除全部临时缓存clear() {Cookies.remove('token');window.sessionStorage.clear();},
};

components下新建svgIcon该文件夹下新建index.vue

<template><i v-if="isShowIconSvg" class="el-icon" :style="setIconSvgStyle"><component :is="getIconName" /></i><div v-else-if="isShowIconImg" :style="setIconImgOutStyle"><img :src="getIconName" :style="setIconSvgInsStyle" /></div><i v-else :class="getIconName" :style="setIconSvgStyle" />
</template><script lang="ts">
import { computed, defineComponent } from 'vue';export default defineComponent({name: 'svgIcon',props: {// svg 图标组件名字name: {type: String,},// svg 大小size: {type: Number,default: () => 14,},// svg 颜色color: {type: String,},},setup(props) {// 在线链接、本地引入地址前缀const linesString = ['https', 'http', '/src', '/assets', import.meta.env.VITE_PUBLIC_PATH];// 获取 icon 图标名称const getIconName = computed(() => {return props?.name;});// 用于判断 element plus 自带 svg 图标的显示、隐藏const isShowIconSvg = computed(() => {return props?.name?.startsWith('ele-');});// 用于判断在线链接、本地引入等图标显示、隐藏const isShowIconImg = computed(() => {return linesString.find((str) => props.name?.startsWith(str));});// 设置图标样式const setIconSvgStyle = computed(() => {return `font-size: ${props.size}px;color: ${props.color};`;});// 设置图片样式const setIconImgOutStyle = computed(() => {return `width: ${props.size}px;height: ${props.size}px;display: inline-block;overflow: hidden;`;});// 设置图片样式// https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0const setIconSvgInsStyle = computed(() => {const filterStyle: string[] = [];const compatibles: string[] = ['-webkit', '-ms', '-o', '-moz'];compatibles.forEach((j) => filterStyle.push(`${j}-filter: drop-shadow(${props.color} 30px 0);`));return `width: ${props.size}px;height: ${props.size}px;position: relative;left: -${props.size}px;${filterStyle.join('')}`;});return {getIconName,isShowIconSvg,isShowIconImg,setIconSvgStyle,setIconImgOutStyle,setIconSvgInsStyle,};},
});
</script>

utils下新建other.ts

import { nextTick } from 'vue';
import type { App } from 'vue';
import * as svg from '@element-plus/icons-vue';
import router from '@/router/index';
import pinia from '@/stores/index';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/stores/themeConfig';
import { i18n } from '@/i18n/index';
import { Local } from '@/utils/storage';
import SvgIcon from '@/components/svgIcon/index.vue';/*** 导出全局注册 element plus svg 图标* @param app vue 实例* @description 使用:https://element-plus.gitee.io/zh-CN/component/icon.html*/
export function elSvg(app: App) {const icons = svg as any;for (const i in icons) {app.component(`ele-${icons[i].name}`, icons[i]);}app.component('SvgIcon', SvgIcon);
}/*** 设置浏览器标题国际化* @method const title = useTitle(); ==> title()*/
export function useTitle() {const stores = useThemeConfig(pinia);const { themeConfig } = storeToRefs(stores);nextTick(() => {let webTitle = '';const globalTitle: string = themeConfig.value.globalTitle;const { path, meta } = router.currentRoute.value;if (path === '/login') {webTitle = <any>meta.title;} else {webTitle = setTagsViewNameI18n(router.currentRoute.value);}document.title = `${webTitle} - ${globalTitle}` || globalTitle;});
}/*** 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化* @param params 路由 query、params 中的 tagsViewName* @returns 返回当前 tagsViewName 名称*/
export function setTagsViewNameI18n(item: any) {let tagsViewName: any = '';const { query, params, meta } = item;if (query?.tagsViewName || params?.tagsViewName) {if (/\/zh-cn|en|zh-tw\//.test(query?.tagsViewName) || /\/zh-cn|en|zh-tw\//.test(params?.tagsViewName)) {// 国际化const urlTagsParams = (query?.tagsViewName && JSON.parse(query?.tagsViewName)) || (params?.tagsViewName && JSON.parse(params?.tagsViewName));tagsViewName = urlTagsParams[i18n.global.locale.value];} else {// 非国际化tagsViewName = query?.tagsViewName || params?.tagsViewName;}} else {// 非自定义 tagsView 名称tagsViewName = i18n.global.t(<any>meta.title);}return tagsViewName;
}/*** 图片懒加载* @param el dom 目标元素* @param arr 列表数据* @description data-xxx 属性用于存储页面或应用程序的私有自定义数据*/
export const lazyImg = (el: any, arr: any) => {const io = new IntersectionObserver((res) => {res.forEach((v: any) => {if (v.isIntersecting) {const { img, key } = v.target.dataset;v.target.src = img;v.target.onload = () => {io.unobserve(v.target);arr[key]['loading'] = false;};}});});nextTick(() => {document.querySelectorAll(el).forEach((img) => io.observe(img));});
};/*** 全局组件大小* @returns 返回 `window.localStorage` 中读取的缓存值 `globalComponentSize`*/
export const globalComponentSize = (): string => {const stores = useThemeConfig(pinia);const { themeConfig } = storeToRefs(stores);return Local.get('themeConfig')?.globalComponentSize || themeConfig.value?.globalComponentSize;
};/*** 对象深克隆* @param obj 源对象* @returns 克隆后的对象*/
export function deepClone(obj: any) {let newObj: any;try {newObj = obj.push ? [] : {};} catch (error) {newObj = {};}for (const attr in obj) {if (obj[attr] && typeof obj[attr] === 'object') {newObj[attr] = deepClone(obj[attr]);} else {newObj[attr] = obj[attr];}}return newObj;
}/*** 判断是否是移动端*/
export function isMobile() {if (navigator.userAgent.match(/('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i)) {return true;} else {return false;}
}/*** 判断数组对象中所有属性是否为空,为空则删除当前行对象* @description @感谢大黄* @param list 数组对象* @returns 删除空值后的数组对象*/
export function handleEmpty(list: any) {const arr = [];for (const i in list) {const d = [];for (const j in list[i]) {d.push(list[i][j]);}const leng = d.filter((item) => item === '').length;if (leng !== d.length) {arr.push(list[i]);}}return arr;
}/*** 统一批量导出* @method elSvg 导出全局注册 element plus svg 图标* @method useTitle 设置浏览器标题国际化* @method setTagsViewNameI18n 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化* @method lazyImg 图片懒加载* @method globalComponentSize() element plus 全局组件大小* @method deepClone 对象深克隆* @method isMobile 判断是否是移动端* @method handleEmpty 判断数组对象中所有属性是否为空,为空则删除当前行对象*/
const other = {elSvg: (app: App) => {elSvg(app);},useTitle: () => {useTitle();},setTagsViewNameI18n(route: any) {return setTagsViewNameI18n(route);},lazyImg: (el: any, arr: any) => {lazyImg(el, arr);},globalComponentSize: () => {return globalComponentSize();},deepClone: (obj: any) => {return deepClone(obj);},isMobile: () => {return isMobile();},handleEmpty: (list: any) => {return handleEmpty(list);},
};// 统一批量导出
export default other;

修改main.ts

import { createApp } from 'vue';
import pinia from '@/stores/index';
import App from './App.vue';
import router from '@/router/index';
import { i18n } from '@/i18n/index';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';const app = createApp(App);app.use(pinia).use(router).use(ElementPlus).use(i18n);app.mount('#app');

修改App.vue

<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { computed } from 'vue';
import other from '@/utils/other';
// 获取全局组件大小
const getGlobalComponentSize = computed(() => {return other.globalComponentSize();
});
const { messages, locale } = useI18n();
// 获取全局 i18n
const getGlobalI18n = computed(() => {return messages.value[locale.value];
});
</script><template><!--https://element-plus.org/zh-CN/component/config-provider.html#api--><el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n"><el-table mb-1 :data="[]" /><el-pagination :total="100" /></el-config-provider>
</template><style scoped></style>

运行项目查看结果

yarn dev

在这里插入图片描述
在这里插入图片描述

修改为en就会变成英文

参考学习代码地址vue-next-admin

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/99918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dremio:新一代数据湖仓引擎

Dremio数据湖引擎 1、什么是Dremio2、什么是数据湖仓2.1、数据湖仓的历史和演变 3、Dremio查询引擎&#xff08;Dremio Sonar&#xff09;3、Dremio特点1、唯一具有自助式SQL分析功能的数据湖仓2、数据完全开放&#xff0c;无锁定3、亚秒级性能&#xff0c;云数据仓库成本的1/1…

【JavaEE重点知识归纳】第7节:类和对象

目录 一&#xff1a;了解面向对象 1.什么是面向对象 2.面向对象和面向过程区分 二&#xff1a;类定义和使用 1.什么是类 2.练习&#xff1a;定义一个学生类 三&#xff1a;类的实例化 1.什么是实例化 2.类和对象的说明 四&#xff1a;认识this 1.为什么要有this引用…

国内就能使用的chatgpt网页版,包含AIGC应用工具

Chatgpt的出现在多个领域带来了重要的影响。它能够显著提高我们的工作效率&#xff0c;无论是编写文案代码还是回答常见问题&#xff0c;都能在短时间内完成任务。通过Chatgpt&#xff0c;我们能够迅速获取所需答案。随着人工智能技术的不断发展&#xff0c;相信在未来AI能够带…

elasticsearch 8.5.3问题记录

一&#xff1a;解决 elasticsearch 高版本 warning: ignoring JAVA_HOMEC:\Program Files\Java\jdk-11&#xff1b; using bundled JDK if defined JAVA_HOME (set JAVA_HOME%JAVA_HOME%; )示例版本Elasticsearch 8.5.3 可以与 JDK 11 兼容&#xff0c;但不支持 JDK 17。确保选…

Spring Boot中实现发送文本、带附件和HTML邮件

SpringBoot实现发送邮箱 引言 在现代应用程序中&#xff0c;电子邮件通常是不可或缺的一部分。在Spring Boot中&#xff0c;你可以轻松地实现发送不同类型的邮件&#xff0c;包括文本、带附件和HTML邮件。本博客将向你展示如何使用Spring Boot发送这些不同类型的电子邮件。 步…

详细解说iptables 高阶用法,用来完成哪些高效率网络路由策略场景,iptables 实现域名过滤,Linux如何利用iptables屏蔽某些域名?

详细解说iptables 高阶用法,用来完成哪些高效率网络路由策略场景,iptables 实现域名过滤,Linux如何利用iptables屏蔽某些域名? Linux利用iptables屏蔽某些域名 以下规则是屏蔽以 youtube.com 为主的所有一级 二级 三级等域名。 iptables -A OUTPUT -m string --string &qu…

unocss+vite+vue3初使unocss

一、什么是UnoCss&#xff1f; UnoCSS 是一个即时的原子CSS引擎&#xff0c;而非一款框架&#xff0c;因为它并未提供核心工具类&#xff0c;所有功能可以通过预设和内联配置提供。它可以让你用简短的类名来控制元素的样式 原子样式也有很多选择&#xff0c;最著名的就是 Tail…

019 基于Spring Boot的教务管理系统、学生管理系统、课表查询系统

基于Spring Boot的教务管理系统、学生管理系统、课表查询系统 一、系统介绍 本作品主要实现了一个课表查询系统&#xff0c;采用了SSM&#xff08;Spring SpringMVC MyBatis&#xff09;的基础架构。 二、使用技术 spring-bootspring-MVCthymeleafmybatis-plusdruidLombo…

保护 Web 服务器安全性

面向公众的系统&#xff08;如 Web 服务器&#xff09;经常成为攻击者的目标&#xff0c;如果这些业务关键资源没有得到适当的保护&#xff0c;可能会导致安全攻击&#xff0c;从而导致巨大的财务后果&#xff0c;并在客户中失去良好的声誉。 什么是网络服务器审核 当有人想要…

Graph RAG: 知识图谱结合 LLM 的检索增强

本文为大家揭示 NebulaGraph 率先提出的 Graph RAG 方法&#xff0c;这种结合知识图谱、图数据库作为大模型结合私有知识系统的最新技术栈&#xff0c;是 LLM 系列的第三篇&#xff0c;加上之前的图上下文学习、Text2Cypher 这两篇文章&#xff0c;目前 NebulaGraph LLM 相关的…

Folium 笔记:MarkerCluster

在一张地图上以聚簇的形式显示大量的标记&#xff08;markers&#xff09; 举例&#xff1a; import folium from folium.plugins import MarkerCluster import randomm folium.Map(location[45.5236, -122.6750], zoom_start13) # 创建一个基本的地图marker_cluster Marker…

git 取消待推送内容

选择最后一次提交的记录&#xff0c;右键->软合并

k8spod就绪检查失败

pod 一直未就绪 kube-system metrics-server-7764f6c67c-2kts9 0/1 Running 0 10m kubect describe 查看 就绪探针未通过 Normal Started 3m19s kubelet Started container metrics-server Warning Unhealthy 5s (x20 over 2m55s) kubelet Readiness probe failed: HTTP probe…

安全性第一!OpenWRT配置SFTP远程文件传输,实现数据安全保护

文章目录 前言1. openssh-sftp-server 安装2. 安装cpolar工具3.配置SFTP远程访问4.固定远程连接地址 前言 本次教程我们将在OpenWRT上安装SFTP服务&#xff0c;并结合cpolar内网穿透&#xff0c;创建安全隧道映射22端口&#xff0c;实现在公网环境下远程OpenWRT SFTP&#xff…

c++视觉检测-----Canny边缘算子

Canny边缘算子 cv::Canny()是OpenCV库中用于执行Canny边缘检测的函数。Canny边缘检测是一种广泛使用的图像处理技术&#xff0c;用于检测图像中的边缘。 以下是cv::Canny()函数的一般用法和参数&#xff1a; void cv::Canny(cv::InputArray image, // 输入图像&#x…

linux 给根目录扩容(lvm CentOS 7.6 kylinx86)

问题:Linux系统挂载到根目录的磁盘空间满了,如何扩容? 用命令:lsblk 可以查看磁盘和分区情况,可以发现磁盘vda下面的还有大部分空间没有使用。 操作步骤 1、使用 fdisk -l 查看硬盘序号,并用 fdisk 对硬盘操作,格式化成lvm的格式 (用命令lsblk可以看到,挂载到根目录…

【软件测试】博客系统项目测试报告(ssm项目)

文章目录 一. 报告概要二. 引言三. 测试环境四. 测试执行概况及功能测试1. 手工测试1.1 编写测试用例1.2 执行部分测试用例 2. 自动化测试Selenium2.1 编写测试用例2.2自动化测试代码1. 自动化测试工具类2. 博客登录页测试3. 博客注册页4. 博客详情页5. 博客编辑页6. 博客列表页…

【git merge/rebase】详解合并代码、解决冲突

目录 1.概述 2.merge 3.rebase 4.merge和rabase的区别 5.解决冲突 1.概述 在实际开发中&#xff0c;一个项目往往是多个人一起协作的&#xff0c;头天下班前大家把代码交到远端仓库&#xff0c;第二天工作的第一件事情都是从服务器上拉最新的代码&#xff0c;保证代码版本…

12. Java异常及异常处理处理

Java —— 异常及处理 1. 异常2. 异常体系3. 常见Exception4. 异常处理4.1 try finally catch关键字4.2 throws和throw 自定义异常4.3 finally&#xff0c;final&#xff0c;finalize三者的区别 1. 异常 异常&#xff1a;在程序执行过程中发生的意外状况&#xff0c;可能导致程…

【List-Watch】

List-Watch 一、定义二、工作机制三、调度过程 一、定义 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件&#xff0c;向 APIServer 发送命令&#xff0c;在 …