feat: 添加首页顶部栏的全屏,中英文切换,头像退出等功能
This commit is contained in:
parent
972627c32d
commit
d12c14f26f
@ -12,9 +12,12 @@
|
|||||||
"@element-plus/icons-vue": "^2.0.6",
|
"@element-plus/icons-vue": "^2.0.6",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
|
"driver.js": "^0.9.8",
|
||||||
"element-plus": "1.3.0-beta.5",
|
"element-plus": "1.3.0-beta.5",
|
||||||
"lint-staged": "13.0.3",
|
"lint-staged": "13.0.3",
|
||||||
|
"screenfull": "5.1.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
|
"vue-i18n": "^9.2.0-beta.40",
|
||||||
"vue-router": "^4.0.3",
|
"vue-router": "^4.0.3",
|
||||||
"vuex": "^4.0.0"
|
"vuex": "^4.0.0"
|
||||||
},
|
},
|
||||||
@ -28,7 +31,6 @@
|
|||||||
"@vue/cli-plugin-router": "~5.0.0",
|
"@vue/cli-plugin-router": "~5.0.0",
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
"@vue/composition-api": "^1.1.0",
|
|
||||||
"@vue/eslint-config-standard": "^6.1.0",
|
"@vue/eslint-config-standard": "^6.1.0",
|
||||||
"cz-customizable": "^6.3.0",
|
"cz-customizable": "^6.3.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
|
45
src/i18n/en.js
Normal file
45
src/i18n/en.js
Normal 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
32
src/i18n/i18nIndex.js
Normal 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
12
src/i18n/watchlang.js
Normal 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
45
src/i18n/zh.js
Normal 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: '全屏按钮'
|
||||||
|
}
|
||||||
|
}
|
60
src/layout/headers/components/breadCrumb.vue
Normal file
60
src/layout/headers/components/breadCrumb.vue
Normal 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>
|
9
src/layout/headers/components/driver/driverIndex.vue
Normal file
9
src/layout/headers/components/driver/driverIndex.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<svg-icon></svg-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<style></style>
|
26
src/layout/headers/components/hamBurger.vue
Normal file
26
src/layout/headers/components/hamBurger.vue
Normal 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>
|
36
src/layout/headers/components/langChange.vue
Normal file
36
src/layout/headers/components/langChange.vue
Normal 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>
|
31
src/layout/headers/components/screenFull.vue
Normal file
31
src/layout/headers/components/screenFull.vue
Normal 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>
|
27
src/layout/headers/components/userAvatar.vue
Normal file
27
src/layout/headers/components/userAvatar.vue
Normal 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>
|
47
src/layout/headers/hearderIndex.vue
Normal file
47
src/layout/headers/hearderIndex.vue
Normal 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>
|
@ -1,10 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="app-wrapper">
|
<el-container class="app-wrapper">
|
||||||
<el-aside width="200px" class="sidebar-container">
|
<el-aside :width="asideWidth" class="sidebar-container">
|
||||||
<menu-index></menu-index>
|
<Menu />
|
||||||
</el-aside>
|
</el-aside>
|
||||||
<el-container class="container">
|
<el-container
|
||||||
<el-header>Header</el-header>
|
class="container"
|
||||||
|
:class="{ hidderContainer: !$store.getters.siderType }"
|
||||||
|
>
|
||||||
|
<el-header>
|
||||||
|
<Headers />
|
||||||
|
</el-header>
|
||||||
<el-main>
|
<el-main>
|
||||||
<router-view />
|
<router-view />
|
||||||
</el-main>
|
</el-main>
|
||||||
@ -13,7 +18,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -35,7 +47,7 @@ import menuIndex from './menu/menuIndex'
|
|||||||
width: calc(100% - $hideSideBarWidth);
|
width: calc(100% - $hideSideBarWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::v-deep(.el-header) {
|
:deep(.el-header) {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
router
|
router
|
||||||
unique-opened
|
unique-opened
|
||||||
:default-active="defaultActive"
|
:default-active="defaultActive"
|
||||||
|
:collapse="!$store.getters.siderType"
|
||||||
>
|
>
|
||||||
<el-sub-menu
|
<el-sub-menu
|
||||||
:index="item.id"
|
:index="item.id"
|
||||||
@ -20,15 +21,17 @@
|
|||||||
<span>{{ item.authName }}</span>
|
<span>{{ item.authName }}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
:index="'/menu/' + it.path"
|
:index="'/' + it.path"
|
||||||
v-for="it in item.children"
|
v-for="it in item.children"
|
||||||
:key="it.id"
|
:key="it.id"
|
||||||
|
@click="savePath(it.path)"
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<component :is="icon"></component>
|
<component :is="icon"></component>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>{{ it.authName }}</span>
|
<span>{{ $t(`menus.${it.path}`) }}</span>
|
||||||
|
<!-- <span>{{ it.authName }}</span> -->
|
||||||
</template>
|
</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
@ -52,12 +55,12 @@ const initMenusList = async () => {
|
|||||||
initMenusList()
|
initMenusList()
|
||||||
|
|
||||||
// 配合重定向,默认进入 user 界面
|
// 配合重定向,默认进入 user 界面
|
||||||
const defaultActive = ref('/menu/users')
|
// const defaultActive = ref('/users')
|
||||||
|
|
||||||
// const defaultActive = ref(sessionStorage.getItem('path') || '/users')
|
const defaultActive = ref(sessionStorage.getItem('path') || '/users')
|
||||||
// const savePath = (path) => {
|
const savePath = (path) => {
|
||||||
// sessionStorage.setItem('path', `/${path}`)
|
sessionStorage.setItem('path', `/${path}`)
|
||||||
// }
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
@ -7,10 +7,11 @@ import SvgIcon from '@/icons/iconIndex'
|
|||||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
import '@/router/premission'
|
import '@/router/premission'
|
||||||
|
import i18n from './i18n/i18nIndex'
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
SvgIcon(app)
|
SvgIcon(app)
|
||||||
app.use(store).use(router).mount('#app')
|
app.use(store).use(router).use(i18n).mount('#app')
|
||||||
|
|
||||||
// 全局引入 Element 的 icon 组件
|
// 全局引入 Element 的 icon 组件
|
||||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
@ -15,25 +15,22 @@ const routes = [
|
|||||||
// 登录路由
|
// 登录路由
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
|
name: 'Login',
|
||||||
component: zdLogin,
|
component: zdLogin,
|
||||||
meta: {
|
meta: {
|
||||||
title: '登录界面'
|
title: '登录界面'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 将 / 重定向到 /login
|
// 首页菜单界面相关路由
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: '/login'
|
name: '/',
|
||||||
},
|
|
||||||
// 菜单界面相关路由
|
|
||||||
{
|
|
||||||
path: '/menu',
|
|
||||||
component: layoutIndex,
|
component: layoutIndex,
|
||||||
meta: {
|
meta: {
|
||||||
title: '菜单界面'
|
title: '菜单界面'
|
||||||
},
|
},
|
||||||
// 重定向,默认到 菜单界面的 user 分支
|
// 重定向,默认到 菜单界面的 user 分支
|
||||||
redirect: '/menu/users',
|
redirect: '/users',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'users',
|
path: 'users',
|
||||||
|
@ -6,7 +6,7 @@ const whiteList = ['/login']
|
|||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
if (store.getters.token) {
|
if (store.getters.token) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
next('/menu')
|
next('/')
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,25 @@ import { setTokenTime } from '@/utils/auth'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: () => ({ token: localStorage.getItem('token') || '' }),
|
state: () => ({
|
||||||
|
token: localStorage.getItem('token') || '',
|
||||||
|
// 定义菜单收缩按钮的值
|
||||||
|
siderType: true,
|
||||||
|
//
|
||||||
|
lang: localStorage.getItem('lang') || 'zh'
|
||||||
|
}),
|
||||||
mutations: {
|
mutations: {
|
||||||
setToken(state, token) {
|
setToken(state, token) {
|
||||||
state.token = token
|
state.token = token
|
||||||
localStorage.setItem('token', token)
|
localStorage.setItem('token', token)
|
||||||
|
},
|
||||||
|
// 菜单收缩按钮的事件
|
||||||
|
changeSiderType(state) {
|
||||||
|
state.siderType = !state.siderType
|
||||||
|
},
|
||||||
|
// 切换语言显示
|
||||||
|
changeLang(state, lang) {
|
||||||
|
state.lang = lang
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -19,7 +33,7 @@ export default {
|
|||||||
console.log(res)
|
console.log(res)
|
||||||
commit('setToken', res.token)
|
commit('setToken', res.token)
|
||||||
setTokenTime()
|
setTokenTime()
|
||||||
router.replace('/menu')
|
router.replace('/')
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<el-form :model="form" ref="formRef" class="login-form" :rules="rules">
|
<el-form :model="form" ref="formRef" class="login-form" :rules="rules">
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<h3 class="title">用户登录</h3>
|
<h3 class="title">{{ $t('login.title') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<svg-icon icon="user" class="svg-container"></svg-icon>
|
<svg-icon icon="user" class="svg-container"></svg-icon>
|
||||||
@ -26,7 +26,7 @@
|
|||||||
</svg-icon>
|
</svg-icon>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-button type="primary" class="login-button" @click="handleLogin">
|
<el-button type="primary" class="login-button" @click="handleLogin">
|
||||||
登录
|
{{ $t('login.btnTitle') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
@ -104,14 +104,14 @@ $cursor: #fff;
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
::v-deep(.el-form-item) {
|
:deep(.el-form-item) {
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: #454545;
|
color: #454545;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.el-input) {
|
:deep(.el-input) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 47px;
|
height: 47px;
|
||||||
width: 85%;
|
width: 85%;
|
||||||
@ -164,7 +164,7 @@ $cursor: #fff;
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.lang-select) {
|
:deep(.lang-select) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -87,8 +87,8 @@ module.exports = {
|
|||||||
sass: {
|
sass: {
|
||||||
// 12版本用 additionalData:
|
// 12版本用 additionalData:
|
||||||
additionalData: `
|
additionalData: `
|
||||||
@import "@/styles/variables.scss"; // scss文件地址
|
@import "@/styles/variables.scss";
|
||||||
@import "@/styles/mixin.scss"; // scss文件地址
|
@import "@/styles/mixin.scss";
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
yarn.lock
75
yarn.lock
@ -1158,6 +1158,44 @@
|
|||||||
resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
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":
|
"@jridgewell/gen-mapping@^0.1.0":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
|
resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
|
||||||
@ -1759,12 +1797,7 @@
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
prettier "^1.18.2 || ^2.0.0"
|
prettier "^1.18.2 || ^2.0.0"
|
||||||
|
|
||||||
"@vue/composition-api@^1.1.0":
|
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.1.4", "@vue/devtools-api@^6.2.1":
|
||||||
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":
|
|
||||||
version "6.2.1"
|
version "6.2.1"
|
||||||
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
|
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
|
||||||
integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==
|
integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==
|
||||||
@ -3410,6 +3443,11 @@ dotenv@^10.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
resolved "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
||||||
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
|
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:
|
duplexer@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
|
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-formats "^2.1.1"
|
||||||
ajv-keywords "^5.0.0"
|
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:
|
scule@^0.2.1:
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
resolved "https://registry.npmmirror.com/scule/-/scule-0.2.1.tgz#0c1dc847b18e07219ae9a3832f2f83224e2079dc"
|
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"
|
resolved "https://registry.npmmirror.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
|
||||||
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
|
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:
|
source-map@^0.5.6:
|
||||||
version "0.5.7"
|
version "0.5.7"
|
||||||
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||||
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
|
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:
|
sourcemap-codec@^1.4.8:
|
||||||
version "1.4.8"
|
version "1.4.8"
|
||||||
resolved "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
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"
|
resolved "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
|
||||||
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
|
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:
|
vue-loader@^17.0.0:
|
||||||
version "17.0.0"
|
version "17.0.0"
|
||||||
resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb"
|
resolved "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.0.0.tgz#2eaa80aab125b19f00faa794b5bd867b17f85acb"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user