vue3+ts项目04-国际化

news/2024/5/17 19:04:24/文章来源:https://blog.csdn.net/qq_36437991/article/details/133746864
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.luyixian.cn/news_show_558444.aspx

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

相关文章

Pymol做B因子图

分子动力学模拟结束后&#xff0c;获得蛋白的平均结构&#xff0c; 比如获得的平均结构为WT-average.pdb 然后将平均结构导入到Pymol 中&#xff0c;可以得到B因子图。 gmx rmsf -f md_0_100_noPBC.xtc -s md_0_100.tpr -o rmsf-per-residue.xvg -ox average.pdb -oq bfactors…

Android App备案获取公钥、签名MD5值

1.生成签名文件 keytool -genkey -alias 别名XXX -keypass 密码XXX -keyalg RSA -keysize 2048 -validity 36500 -keystore D:\XXX.keystore -storepass 密码XXX2.查看签名MD5值 keytool -list -v -keystore D:\XXX.keystore3.查看公钥 导出证书XXX.cer keytool -export -a…

vue接入高德地图获取经纬度

&#x1f90d;step1:高德地图开放平台&#xff0c;根据指引注册成为高德开放平台开发者&#xff0c;并申请 web 平台&#xff08;JS API&#xff09;的 key 和安全密钥; &#x1f90d;step2:在html引入安全密钥&#xff08;获取经纬度用&#xff0c;不然会报错&#xff09; <…

uniapp上echarts地图钻取

1: 预期效果 通过切换地图 , 实现地图的钻取效果 2: 实现原理以及核心方法/参数 一开始是想利用更换地图数据的形式进行地图钻取 , 这就意味着我们需要准备全国30多个省份的地图数据 , 由于一开始考虑需要适配小程序端 , 如此多的地图文件增加了程序的体积 , 如果使用接口调…

spring 事务源码阅读之实现原理

开启事务 使用EnableTransactionManagement注解开启事务 该注解会引入TransactionManagementConfigurationSelector类&#xff0c;然后该类导入两个类AutoProxyRegistrar和ProxyTransactionManagementConfiguration。 1、添加bean后置处理器 AutoProxyRegistrar类的作用是注…

大数据学习(2)Hadoop-分布式资源计算hive(1)

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博>主哦&#x…

前端uniapp生成海报并保存相册

uiapp插件 目录 图片qrcode.vue源码完整版封装源码qrcodeSwiper.vue最后 图片 qrcode.vue源码完整版 <template><view class"qrcode"><div class"qrcode_swiper SourceHanSansSC-Normal"><!-- <cc-scroolCard :dataInfo"dat…

10-09 周一 图解机器学习之深度学习感知机学习

10-09 周一 图解机器学习之深度学习感知机学习 时间版本修改人描述2023年10月9日14:13:20V0.1宋全恒新建文档 简介 感知机是神经网络中的概念&#xff0c;1958年被Frank Rosenblatt第一次引入。感知机作为一种基本的神经网络模型&#xff0c;它模拟了人脑神经元的工作原理。感…

Python+requests+Excel数据驱动的接口自动化测试中解决接口间数据依赖

在实际的测试工作中&#xff0c;在做接口自动化过程中往往会遇到接口间数据依赖问题&#xff0c;即API_03的请求参数来源与API_02的响应数据&#xff0c;API_02的请求参数又来源与API_01的响应数据&#xff0c;因此通过自动化方式测试API_03接口时&#xff0c;需要预先请求API_…

山西电力市场日前价格预测【2023-10-11】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-11&#xff09;山西电力市场全天平均日前电价为507.37元/MWh。其中&#xff0c;最高日前电价为873.70元/MWh&#xff0c;预计出现在18: 45。最低日前电价为313.23元/MWh&#xff0c;预计…

阿里云数据库MongoDB恢复到本地

共两种方式&#xff0c;建议使用第二种的逻辑恢复&#xff0c;比较方便快捷 一、下载物理备份文件 下载的格式是xb的&#xff0c;主要跟实例创建时间有关&#xff0c;2019年03月26日之前创建的实例&#xff0c;物理备份文件格式为tar&#xff0c;后面全部都是xb的格式了&#…

PTA 7-3 插松枝(单调栈)

题目7-3 插松枝 人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。 每人面前有用不完的松枝干和一个推送器&#…

C++ 获取文件创建时间、修改时间、大小等属性

简介 获取文件创建时间、修改时间、大小等属性 代码 #include <iostream> #include <string.h> #include <time.h>void main() {std::string filename "E:\\LiHai123.txt";struct _stat stat_buffer;int result _stat(filename.c_str(), &s…

shein汇总

如何将mysql的数据同步到es 1、使用Canal&#xff1a;Canal是阿里巴巴开源的一款基于MySQL数据库增量日志解析和同步的工具。Canal可以将MySQL中的数据同步到ES中&#xff0c;支持多种数据格式和数据源。 2、使用自定义脚本&#xff1a;可以编写自定义脚本&#xff0c;通过My…

C语言利用计算机找系统的最小通路集的算法

背景&#xff1a; 有人求助到博主希望分析一下他们老师给出的题目&#xff0c;博主思路分析和解题过程如下 题目要求&#xff1a; 联络矩阵法&#xff0c;当 n 较小时可以用手算,当然也可以用计算机计算。但当 n 很大时&#xff0c;需要计 算机的容量很大才行。为此要探求有…

git 取消待推送内容

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

MyCat-web安装文档:安装Zookeeper、安装Mycat-web

安装Zookeeper A. 上传安装包 zookeeper-3.4.6.tar.gzB. 解压 #解压到当前目录&#xff0c;之后会生成一个安装后的目录 tar -zxvf zookeeper-3.4.6.tar.gz#加上-c 代表解压到指定目录 tar -zxvf zookeeper-3.4.6.tar.gz -C /usr/local/C. 在安装目录下&#xff0c;创建数据…

与创新者同行!Apache Doris 首届线下峰会即将开启,最新议程公开!|即刻预约

点击此处 即刻报名 Doris Summit Asia 2023 回顾人类的发展史&#xff0c;地球起源于 46 亿年前的原始星云、地球生命最初出现于 35 亿年前的原始海洋、人类物种诞生于数百万年前&#xff0c;而人类生产力的真正提升源于十八世纪六十年代的工业革命&#xff0c;自此以后&#…

【脑机接口论文与代码】High-speed spelling with a noninvasive brain–computer interface

High-speed spelling with a noninvasive brain–computer interface 中文题目 &#xff1a;非侵入性的高速拼写脑机接口论文下载算法程序下载摘要1 项目介绍2 方法2.1SSVEPs的基波和谐波分量JFPM刺激产生算法2.3基波和谐波SSVEP分量的幅度谱和信噪比 3讨论4实验环境设置与方法…

2023-10-10-C++指针和引用【程序员生涯的第一座里程碑】

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…