feat: 添加首页顶部栏的全屏,中英文切换,头像退出等功能

This commit is contained in:
gis-xh 2022-07-25 19:37:18 +08:00
parent 972627c32d
commit d12c14f26f
21 changed files with 495 additions and 43 deletions

View File

@ -12,9 +12,12 @@
"@element-plus/icons-vue": "^2.0.6",
"axios": "^0.27.2",
"core-js": "^3.8.3",
"driver.js": "^0.9.8",
"element-plus": "1.3.0-beta.5",
"lint-staged": "13.0.3",
"screenfull": "5.1.0",
"vue": "^3.2.13",
"vue-i18n": "^9.2.0-beta.40",
"vue-router": "^4.0.3",
"vuex": "^4.0.0"
},
@ -28,7 +31,6 @@
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/composition-api": "^1.1.0",
"@vue/eslint-config-standard": "^6.1.0",
"cz-customizable": "^6.3.0",
"eslint": "^7.32.0",

45
src/i18n/en.js Normal file
View File

@ -0,0 +1,45 @@
export default {
menus: {
'/': 'home',
home: 'home',
users: 'users list',
roles: 'roles list',
rights: 'permission list',
goods: 'product list',
params: 'sorting list',
categories: 'goods category',
orders: 'order list',
reports: 'data report'
},
login: {
title: 'user login',
btnTitle: 'login'
},
dialog: {
deleteTitle: 'Are you sure you want to delete the user '
},
table: {
username: 'username',
email: 'email',
mobile: 'mobile',
role_name: 'role name',
mg_state: 'state',
create_time: 'create_time',
action: 'action',
search: 'search',
adduser: 'add user',
placeholder: 'Please enter a user name to search for'
},
message: {
updeteSuccess: 'update successfully'
},
driver: {
doneBtnText: 'done',
closeBtnText: 'close',
nextBtnText: 'next',
prevBtnText: 'prev',
guideBtn: 'guidebtn',
hamburgerBtn: 'hamburgerBtn',
fullScreen: 'fullScreen'
}
}

32
src/i18n/i18nIndex.js Normal file
View File

@ -0,0 +1,32 @@
import { createI18n } from 'vue-i18n'
import EN from './en'
import ZH from './zh'
const messages = {
en: {
...EN
},
zh: {
...ZH
}
}
// 设置当前语言
const getCurrentLanguage = () => {
// 浏览器设置语言
const UAlang = navigator.language
// 判断语言
const langCode = UAlang.indexOf('zh') !== -1 ? 'zh' : 'en'
// 缓存语言信息
localStorage.setItem('lang', langCode)
return langCode
}
// 创建 i18n 国际化
const i18n = createI18n({
legacy: false,
globalInjection: true,
locale: getCurrentLanguage() || 'zh',
messages: messages
})
export default i18n

12
src/i18n/watchlang.js Normal file
View File

@ -0,0 +1,12 @@
import { watch } from 'vue'
import store from '@/store'
export const watchLang = (...cbs) => {
watch(
() => store.getters.lang,
() => {
cbs.forEach((cb) => cb(store.getters.lang))
},
{ deep: true }
)
}

45
src/i18n/zh.js Normal file
View File

@ -0,0 +1,45 @@
export default {
menus: {
'/': '首页',
home: '首页',
users: '用户列表',
roles: '角色列表',
rights: '权限列表',
goods: '商品列表',
params: '分类参数',
categories: '商品分类',
orders: '订单列表',
reports: '数据报表'
},
login: {
title: '用户登录',
btnTitle: '登录'
},
dialog: {
deleteTitle: '确定要删除用户'
},
table: {
username: '姓名',
email: '邮箱',
mobile: '手机',
role_name: '角色',
mg_state: '状态',
create_time: '创建时间',
action: '操作',
search: '搜索',
adduser: '添加用户',
placeholder: '请输入搜索的用户姓名'
},
message: {
updeteSuccess: '更新成功'
},
driver: {
doneBtnText: '完成',
closeBtnText: '关闭',
nextBtnText: '下一步',
prevBtnText: '上一步',
guideBtn: '引导按钮',
hamburgerBtn: '汉堡按钮',
fullScreen: '全屏按钮'
}
}

View File

@ -0,0 +1,60 @@
<template>
<!-- <el-breadcrumb :separator-icon="ArrowRight"> -->
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="index">
<span class="no-redirect" v-if="index === breadcrumbList.length - 1">
{{ $t(`menus.${item.name}`) }}
</span>
<span class="redirect" v-else @click="handleRedirect(item.path)">
{{ $t(`menus.${item.name}`) }}
</span>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup>
// import { ArrowRight } from '@element-plus/icons-vue'
import { watch, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
//
const route = useRoute()
//
const router = useRouter()
const breadcrumbList = ref([])
//
const initBreadcrumbList = () => {
breadcrumbList.value = route.matched
console.log(route.matched)
}
//
const handleRedirect = (path) => {
router.push(path)
}
//
watch(
route,
() => {
initBreadcrumbList()
},
{ deep: true, immediate: true }
)
</script>
<style lang="scss" scoped>
.no-redirect {
color: #97a8be;
cursor: text;
}
.redirect {
color: #666;
font-weight: 600;
cursor: pointer;
&:hover {
color: $menuBg;
}
}
</style>

View File

@ -0,0 +1,9 @@
<template>
<div>
<svg-icon></svg-icon>
</div>
</template>
<script setup></script>
<style></style>

View File

@ -0,0 +1,26 @@
<template>
<div class="hamburger-container" @click="toggleClick" id="hamburger">
<svg-icon :icon="icon"></svg-icon>
</div>
</template>
<script setup>
import { useStore } from 'vuex'
import { computed } from 'vue'
const store = useStore()
const toggleClick = () => {
store.commit('app/changeSiderType')
}
const icon = computed(() => {
return store.getters.siderType ? 'hamburger-opened' : 'hamburger-closed'
})
</script>
<style lang="scss" scoped>
.hamburger-container {
margin-right: 16px;
box-sizing: border-box;
//
cursor: pointer;
}
</style>

View File

@ -0,0 +1,36 @@
<template>
<el-dropdown @command="handleCommand">
<svg-icon icon="language"></svg-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="zh" :disabled="currentLanguage === 'zh'"
>中文</el-dropdown-item
>
<el-dropdown-item command="en" :disabled="currentLanguage === 'en'"
>English</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
import { useStore } from 'vuex'
const i18n = useI18n()
const store = useStore()
// (zh / en)
const currentLanguage = computed(() => {
return i18n.locale.value
})
//
const handleCommand = (val) => {
i18n.locale.value = val
store.commit('app/changeLang', val)
localStorage.setItem('lang', val)
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,31 @@
<template>
<div @click="handleFullScreen" id="screenFul">
<svg-icon :icon="icon ? 'exit-fullscreen' : 'fullscreen'"></svg-icon>
</div>
</template>
<script setup>
import screenfull from 'screenfull'
import { ref, onMounted, onBeforeMount } from 'vue'
const icon = ref(screenfull.isFullscreen)
const handleFullScreen = () => {
if (screenfull.isEnabled) {
screenfull.toggle()
}
}
const changeIcon = () => {
icon.value = screenfull.isFullscreen
}
onMounted(() => {
screenfull.on('change', changeIcon)
})
onBeforeMount(() => {
screenfull.off('change')
})
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,27 @@
<template>
<el-dropdown>
<el-avatar shape="square" :size="50" :src="squareUrl" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="logout">退出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup>
import { ref } from 'vue'
import { useStore } from 'vuex'
const squareUrl = ref(
'https://portrait.gitee.com/uploads/avatars/user/1818/5455629_gis-xh_1589789228.png!avatar60'
)
const store = useStore()
const logout = () => {
store.dispatch('app/logout')
}
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,47 @@
<template>
<div class="navbar">
<Hamburger />
<Breadcrumb />
<div class="navbar-right">
<Screenfull class="navbar-item" />
<Langchange class="navbar-item" />
<Useravatar class="navbar-item" />
</div>
</div>
</template>
<script setup>
import Hamburger from './components/hamBurger.vue'
import Breadcrumb from './components/breadCrumb.vue'
import Useravatar from './components/userAvatar.vue'
import Langchange from './components/langChange.vue'
import Screenfull from './components/screenFull.vue'
</script>
<style lang="scss" scoped>
.navbar {
width: 100%;
height: 60px;
overflow: hidden;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
padding: 0 16px;
display: flex;
align-items: center;
box-sizing: border-box;
position: relative;
.navbar-right {
flex: 1;
display: flex;
align-items: center;
justify-content: flex-end;
:deep(.navbar-item) {
display: inline-block;
margin-left: 18px;
font-size: 22px;
color: #5a5e66;
box-sizing: border-box;
cursor: pointer;
}
}
}
</style>

View File

@ -1,10 +1,15 @@
<template>
<el-container class="app-wrapper">
<el-aside width="200px" class="sidebar-container">
<menu-index></menu-index>
<el-aside :width="asideWidth" class="sidebar-container">
<Menu />
</el-aside>
<el-container class="container">
<el-header>Header</el-header>
<el-container
class="container"
:class="{ hidderContainer: !$store.getters.siderType }"
>
<el-header>
<Headers />
</el-header>
<el-main>
<router-view />
</el-main>
@ -13,7 +18,14 @@
</template>
<script setup>
import menuIndex from './menu/menuIndex'
import Menu from './menu/menuIndex'
import Headers from './headers/hearderIndex.vue'
import { computed } from 'vue'
import { useStore } from 'vuex'
const store = useStore()
const asideWidth = computed(() => {
return store.getters.siderType ? '$sideBarWidth' : '$hideSideBarWidth'
})
</script>
<style lang="scss" scoped>
@ -35,7 +47,7 @@ import menuIndex from './menu/menuIndex'
width: calc(100% - $hideSideBarWidth);
}
}
::v-deep(.el-header) {
:deep(.el-header) {
padding: 0;
}
</style>

View File

@ -7,6 +7,7 @@
router
unique-opened
:default-active="defaultActive"
:collapse="!$store.getters.siderType"
>
<el-sub-menu
:index="item.id"
@ -20,15 +21,17 @@
<span>{{ item.authName }}</span>
</template>
<el-menu-item
:index="'/menu/' + it.path"
:index="'/' + it.path"
v-for="it in item.children"
:key="it.id"
@click="savePath(it.path)"
>
<template #title>
<el-icon>
<component :is="icon"></component>
</el-icon>
<span>{{ it.authName }}</span>
<span>{{ $t(`menus.${it.path}`) }}</span>
<!-- <span>{{ it.authName }}</span> -->
</template>
</el-menu-item>
</el-sub-menu>
@ -52,12 +55,12 @@ const initMenusList = async () => {
initMenusList()
// user
const defaultActive = ref('/menu/users')
// const defaultActive = ref('/users')
// const defaultActive = ref(sessionStorage.getItem('path') || '/users')
// const savePath = (path) => {
// sessionStorage.setItem('path', `/${path}`)
// }
const defaultActive = ref(sessionStorage.getItem('path') || '/users')
const savePath = (path) => {
sessionStorage.setItem('path', `/${path}`)
}
</script>
<style lang="scss" scoped></style>

View File

@ -7,10 +7,11 @@ import SvgIcon from '@/icons/iconIndex'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import 'element-plus/dist/index.css'
import '@/router/premission'
import i18n from './i18n/i18nIndex'
const app = createApp(App)
SvgIcon(app)
app.use(store).use(router).mount('#app')
app.use(store).use(router).use(i18n).mount('#app')
// 全局引入 Element 的 icon 组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {

View File

@ -15,25 +15,22 @@ const routes = [
// 登录路由
{
path: '/login',
name: 'Login',
component: zdLogin,
meta: {
title: '登录界面'
}
},
// 将 / 重定向到 /login
// 首页菜单界面相关路由
{
path: '/',
redirect: '/login'
},
// 菜单界面相关路由
{
path: '/menu',
name: '/',
component: layoutIndex,
meta: {
title: '菜单界面'
},
// 重定向,默认到 菜单界面的 user 分支
redirect: '/menu/users',
redirect: '/users',
children: [
{
path: 'users',

View File

@ -6,7 +6,7 @@ const whiteList = ['/login']
router.beforeEach((to, from, next) => {
if (store.getters.token) {
if (to.path === '/login') {
next('/menu')
next('/')
} else {
next()
}

View File

@ -4,11 +4,25 @@ import { setTokenTime } from '@/utils/auth'
export default {
namespaced: true,
state: () => ({ token: localStorage.getItem('token') || '' }),
state: () => ({
token: localStorage.getItem('token') || '',
// 定义菜单收缩按钮的值
siderType: true,
//
lang: localStorage.getItem('lang') || 'zh'
}),
mutations: {
setToken(state, token) {
state.token = token
localStorage.setItem('token', token)
},
// 菜单收缩按钮的事件
changeSiderType(state) {
state.siderType = !state.siderType
},
// 切换语言显示
changeLang(state, lang) {
state.lang = lang
}
},
actions: {
@ -19,7 +33,7 @@ export default {
console.log(res)
commit('setToken', res.token)
setTokenTime()
router.replace('/menu')
router.replace('/')
resolve()
})
.catch((err) => {

View File

@ -2,7 +2,7 @@
<div class="login-container">
<el-form :model="form" ref="formRef" class="login-form" :rules="rules">
<div class="title-container">
<h3 class="title">用户登录</h3>
<h3 class="title">{{ $t('login.title') }}</h3>
</div>
<el-form-item prop="username">
<svg-icon icon="user" class="svg-container"></svg-icon>
@ -26,7 +26,7 @@
</svg-icon>
</el-form-item>
<el-button type="primary" class="login-button" @click="handleLogin">
登录
{{ $t('login.btnTitle') }}
</el-button>
</el-form>
</div>
@ -104,14 +104,14 @@ $cursor: #fff;
margin: 0 auto;
overflow: hidden;
::v-deep(.el-form-item) {
:deep(.el-form-item) {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
::v-deep(.el-input) {
:deep(.el-input) {
display: inline-block;
height: 47px;
width: 85%;
@ -164,7 +164,7 @@ $cursor: #fff;
font-weight: bold;
}
::v-deep(.lang-select) {
:deep(.lang-select) {
position: absolute;
top: 4px;
right: 0;

View File

@ -87,8 +87,8 @@ module.exports = {
sass: {
// 12版本用 additionalData:
additionalData: `
@import "@/styles/variables.scss"; // scss文件地址
@import "@/styles/mixin.scss"; // scss文件地址
@import "@/styles/variables.scss";
@import "@/styles/mixin.scss";
`
}
}

View File

@ -1158,6 +1158,44 @@
resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@intlify/core-base@9.2.0-beta.40":
version "9.2.0-beta.40"
resolved "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.2.0-beta.40.tgz#85df2e183b2102716c5d40795848fc2359354580"
integrity sha512-vOR0lHgtJ3IkzvXLeMQeNeYreFSKG9v3SU8QOD//WKHdBy4QPISs9CZJkYzBeBVCJVZ/eM6OTSbXF8M2k53iCw==
dependencies:
"@intlify/devtools-if" "9.2.0-beta.40"
"@intlify/message-compiler" "9.2.0-beta.40"
"@intlify/shared" "9.2.0-beta.40"
"@intlify/vue-devtools" "9.2.0-beta.40"
"@intlify/devtools-if@9.2.0-beta.40":
version "9.2.0-beta.40"
resolved "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.2.0-beta.40.tgz#bee42fefaaaa590aa5ac7fe2a98777fb84bfaf5e"
integrity sha512-EUiuLxlgortD1dhT0btm3YYIs2vk9kMdcGXiYYbHWRTylc8Iv7Yz47y5Y+IlbZzk51h/nYvuqXE1h9diZZWAvQ==
dependencies:
"@intlify/shared" "9.2.0-beta.40"
"@intlify/message-compiler@9.2.0-beta.40":
version "9.2.0-beta.40"
resolved "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.2.0-beta.40.tgz#d5d0c5652b9e74e0b4da07a2b8731e1f0e729029"
integrity sha512-6QWTSYewmkew4nsRqgkwTVuGFKzxVCOK8EXsPt15N+tN1g+OYjC3PfGA2dPB6cVkNxqA9mV/hNK02uHPWU9t0A==
dependencies:
"@intlify/shared" "9.2.0-beta.40"
source-map "0.6.1"
"@intlify/shared@9.2.0-beta.40":
version "9.2.0-beta.40"
resolved "https://registry.npmmirror.com/@intlify/shared/-/shared-9.2.0-beta.40.tgz#a850936008e6e865310b2a49136d494dd326faab"
integrity sha512-xWz+SFjgt/LfaSbbHVn+V7gmvX4ZNP3cIFta790GWZ/tEgwJeC3tkV7i45iUbZ4ZimOerFgKH05b7qvJlKb6RQ==
"@intlify/vue-devtools@9.2.0-beta.40":
version "9.2.0-beta.40"
resolved "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.2.0-beta.40.tgz#37457fd719b0b6afb0679c33ceb47b0ac77f457c"
integrity sha512-3A0D/E9quf+KWonzXUDk3xNP0+d1DMdtAwyXNTjzFcQPvjugC2Xn6fmsd0kNn7nHjgpB+vwIuamGiuE+S+OULw==
dependencies:
"@intlify/core-base" "9.2.0-beta.40"
"@intlify/shared" "9.2.0-beta.40"
"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
@ -1759,12 +1797,7 @@
optionalDependencies:
prettier "^1.18.2 || ^2.0.0"
"@vue/composition-api@^1.1.0":
version "1.7.0"
resolved "https://registry.npmmirror.com/@vue/composition-api/-/composition-api-1.7.0.tgz#26fae79e5023fc6c9dfd99ca5d3d357e1c5b9c60"
integrity sha512-hxOgLYR+wjuPX9bkP2pAPlqUs98XxBoa9DSLyp1z6+YR92wC42PZcZKs4d+VRtcv4udOv041Kss+F6ap5nj8YA==
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.1.4":
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.1.4", "@vue/devtools-api@^6.2.1":
version "6.2.1"
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==
@ -3410,6 +3443,11 @@ dotenv@^10.0.0:
resolved "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
driver.js@^0.9.8:
version "0.9.8"
resolved "https://registry.npmmirror.com/driver.js/-/driver.js-0.9.8.tgz#4b327f4537b1c9b9fb19419de86174be821ae32a"
integrity sha512-bczjyKdX6XmFyCDkwtRmlaORDwfBk1xXmRO0CAe5VwNQTM98aWaG2LAIiIdTe53iV/B7W5lXlIy2xYtf0JRb7Q==
duplexer@^0.1.2:
version "0.1.2"
resolved "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
@ -7047,6 +7085,11 @@ schema-utils@^4.0.0:
ajv-formats "^2.1.1"
ajv-keywords "^5.0.0"
screenfull@5.1.0:
version "5.1.0"
resolved "https://registry.npmmirror.com/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8"
integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA==
scule@^0.2.1:
version "0.2.1"
resolved "https://registry.npmmirror.com/scule/-/scule-0.2.1.tgz#0c1dc847b18e07219ae9a3832f2f83224e2079dc"
@ -7320,16 +7363,16 @@ source-map-url@^0.4.0:
resolved "https://registry.npmmirror.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
sourcemap-codec@^1.4.8:
version "1.4.8"
resolved "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
@ -8142,6 +8185,16 @@ vue-hot-reload-api@^2.3.0:
resolved "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
vue-i18n@^9.2.0-beta.40:
version "9.2.0-beta.40"
resolved "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.2.0-beta.40.tgz#8088b19d619f47bf0e0f529f9bd1413460f2ff56"
integrity sha512-UwcGsbTTaDJry6BbFFzt115EVHN/bXi07DyUIZ4zrYeGMBPp2QAptMwVaGUQid1gaMmUreAKarGIqw46oCQEvg==
dependencies:
"@intlify/core-base" "9.2.0-beta.40"
"@intlify/shared" "9.2.0-beta.40"
"@intlify/vue-devtools" "9.2.0-beta.40"
"@vue/devtools-api" "^6.2.1"
vue-loader@^17.0.0:
version "17.0.0"
resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb"