perf:优化缓存,布局,样式
This commit is contained in:
parent
a985df0af7
commit
15d7e0c555
|
|
@ -2,9 +2,9 @@
|
|||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue + TS</title>
|
||||
<title>Vue admin perfect</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb" mode="out-in">
|
||||
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
|
||||
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
||||
<el-breadcrumb-item v-for="(item, index) in matched" :key="item.name">
|
||||
<span v-if="item.redirect === 'noRedirect' || index == matched.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
|
|
@ -11,45 +11,20 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { onMounted, ref, watch,computed } from 'vue'
|
||||
import { useRoute ,useRouter} from 'vue-router'
|
||||
|
||||
const levelList = ref([])
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
// 获取面包屑
|
||||
const getBreadcrumb = () => {
|
||||
let matched = route.matched.filter((item) => item.meta && item.meta.title)
|
||||
const first = matched[0]
|
||||
levelList.value = matched.filter(
|
||||
(item) => item.meta && item.meta.title && item.meta.breadcrumb !== false,
|
||||
)
|
||||
}
|
||||
|
||||
const handleLink = ()=>{
|
||||
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getBreadcrumb()
|
||||
watch(route, () => {
|
||||
if (route.path.startsWith('/redirect/')) {
|
||||
return
|
||||
}
|
||||
getBreadcrumb()
|
||||
const handleLink = (item)=>{
|
||||
router.push({
|
||||
path:item.path
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const matched = computed(() => route.matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false));
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
.no-redirect {
|
||||
color:#303133;
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
<el-form-item label="姓名">
|
||||
<el-input v-model="ruleForm.name" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码">
|
||||
<el-input v-model="ruleForm.mobile" disabled></el-input>
|
||||
<el-form-item label="旧的密码" prop="password">
|
||||
<el-input v-model="ruleForm.password" type="password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="修改密码" prop="password">
|
||||
<el-input v-model="ruleForm.password"></el-input>
|
||||
<el-form-item label="新的密码" prop="configPassword">
|
||||
<el-input v-model="ruleForm.configPassword" type="password"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
|
@ -29,9 +29,10 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { ref, defineExpose, reactive } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import type { ElForm } from 'element-plus'
|
||||
const dialogVisible = ref(false)
|
||||
import {useUserStore} from "@/store/modules/user"
|
||||
const UserStore = useUserStore()
|
||||
const show = () => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
|
@ -43,15 +44,15 @@
|
|||
const formSize = ref('')
|
||||
const ruleFormRef = ref<FormInstance>()
|
||||
const ruleForm = reactive({
|
||||
name: '',
|
||||
mobile: '',
|
||||
password: '',
|
||||
name: UserStore.userInfo.username,
|
||||
password: UserStore.userInfo.password,
|
||||
configPassword: '',
|
||||
})
|
||||
const rules = reactive({
|
||||
password: [
|
||||
configPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入密码',
|
||||
message: '请输入新的密码',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -33,5 +33,9 @@ const setAssemblySize = (item: string) => {
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.transverseMenu {
|
||||
.size-icon {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@
|
|||
<div
|
||||
class="m-layout-header"
|
||||
:class="[
|
||||
SettingStore.themeConfig.fixedHeader&&'zb-fixed-header',
|
||||
isCollapse?'fixed-header-collapse':'fixed-header-no-collapse'
|
||||
SettingStore.themeConfig.fixedHeader?'zb-fixed-header':'zb-no-fixed-header',
|
||||
mode === 'horizontal'?'':isCollapse?'fixed-header-collapse':'fixed-header-no-collapse'
|
||||
]"
|
||||
|
||||
>
|
||||
<!-- :style="{ left: `${mode === 'horizontal' ? 0 : isCollapse ? '60' : '210'}px` }"-->
|
||||
<div
|
||||
class="header"
|
||||
:class="{
|
||||
|
|
@ -16,7 +14,7 @@
|
|||
>
|
||||
<u-menu v-if="mode === 'horizontal'" />
|
||||
<div class="left" v-if="mode === 'vertical'">
|
||||
<div>
|
||||
<div class="hamburger-container">
|
||||
<el-icon class="icon" v-if="isCollapse" @click="handleCollapse"><expand /></el-icon>
|
||||
<el-icon class="icon" v-else @click="handleCollapse"><fold /></el-icon>
|
||||
</div>
|
||||
|
|
@ -44,8 +42,10 @@
|
|||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :command="1">退出登录</el-dropdown-item>
|
||||
<el-dropdown-item :command="2">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item :command="2" >
|
||||
<el-icon><Edit /></el-icon>修改密码</el-dropdown-item>
|
||||
<el-dropdown-item :command="1" divided>
|
||||
<el-icon><SwitchButton /></el-icon>退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
|
@ -98,10 +98,14 @@
|
|||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await UserStore.logout()
|
||||
router.push({ path: '/login' })
|
||||
await UserStore.logout()
|
||||
PermissionStore.clearRoutes()
|
||||
TagsViewStore.clearVisitedView()
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "退出登录成功!"
|
||||
});
|
||||
} catch (e) {}
|
||||
})
|
||||
.catch(() => {})
|
||||
|
|
@ -139,12 +143,13 @@
|
|||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
padding: 0 10px 0 0;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
.right {
|
||||
display: flex;
|
||||
|
|
@ -160,7 +165,18 @@
|
|||
right: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.zb-no-fixed-header{
|
||||
width: 100%!important;;
|
||||
}
|
||||
.hamburger-container{
|
||||
padding: 0px 15px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, .025)
|
||||
}
|
||||
}
|
||||
.m-layout-header {
|
||||
width: 100%;
|
||||
background: white;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
background-color="#304156"
|
||||
text-color="#fff"
|
||||
text-color="#bfcbd9"
|
||||
:mode="mode"
|
||||
:unique-opened="SettingStore.themeConfig.uniqueOpened"
|
||||
:collapse-transition="false"
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
import { useRoute } from 'vue-router'
|
||||
import {usePermissionStore} from "@/store/modules/permission"
|
||||
import {useSettingStore} from "@/store/modules/setting"
|
||||
import { ref, computed } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
// 在setup中获取store
|
||||
const route = useRoute()
|
||||
|
|
@ -33,8 +33,6 @@
|
|||
// 获取路由
|
||||
const permission_routes = computed(() => PermissionStore.permission_routes)
|
||||
|
||||
|
||||
|
||||
const activeMenu = computed(() => {
|
||||
const { meta, path } = route
|
||||
// if set path, the sidebar will highlight the path you set
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
import UMenu from './components/Menu.vue'
|
||||
import logo from './components/Logo.vue'
|
||||
import {useSettingStore} from "@/store/modules/setting"
|
||||
import { ref, computed } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const SettingStore = useSettingStore()
|
||||
// 是否折叠
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Layout from "@/layout/index.vue";
|
|||
const chartsRouter = {
|
||||
path: '/charts',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/charts/migration',
|
||||
name: 'Charts',
|
||||
meta: {
|
||||
title: '可视化图表',
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Layout from "@/layout/index.vue";
|
|||
const chartsRouter = {
|
||||
path: '/chat',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/charts/index',
|
||||
name: 'chat',
|
||||
meta: {
|
||||
title: '聊天框',
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Layout from '@/layout/index.vue'
|
|||
const clipboardTable = {
|
||||
path: '/clipboard',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/clipboard/index',
|
||||
name: 'clipboard',
|
||||
meta: {
|
||||
title: 'clipboard',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Layout from "@/layout/index.vue";
|
|||
const errorRouter = {
|
||||
path: '/error',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/error/404',
|
||||
name: 'error',
|
||||
meta: {
|
||||
title: '错误页面',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Layout from "@/layout/index.vue";
|
|||
const excelRouter = {
|
||||
path: '/excel',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/excel/export-excel',
|
||||
name: 'excel',
|
||||
meta: {
|
||||
title: 'Excel',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import Layout from "@/layout/index.vue";
|
|||
const formRouter = {
|
||||
path: '/form',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/form/validateForm',
|
||||
name: 'form',
|
||||
alwaysShow:true,
|
||||
meta: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Layout from "@/layout/index.vue";
|
|||
const nestedRouter = {
|
||||
path: '/nested',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/form/menu1',
|
||||
name: 'nested',
|
||||
meta: {
|
||||
title: '路由嵌套',
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Layout from '@/layout/index.vue'
|
|||
const othersRouter = {
|
||||
path: '/other',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/other/editor',
|
||||
name: 'other',
|
||||
meta: {
|
||||
title: '扩展组件',
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Layout from '@/layout/index.vue'
|
|||
const systemRouter = {
|
||||
path: '/system',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/system/page',
|
||||
name: 'system',
|
||||
meta: {
|
||||
title: '系统管理',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import Layout from "@/layout/index.vue";
|
|||
const tableRouter = {
|
||||
path: '/table',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
redirect: '/table/comprehensive',
|
||||
name: 'table',
|
||||
meta: {
|
||||
title: '超级表格',
|
||||
|
|
|
|||
|
|
@ -104,7 +104,14 @@ html.dark {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.zb-pro-table .header{
|
||||
background: none!important;
|
||||
border: var(--zb-border-light);
|
||||
}
|
||||
.zb-pro-table .footer{
|
||||
background: none!important;
|
||||
border: var(--zb-border-light);
|
||||
}
|
||||
// m-layout-header
|
||||
.m-layout-header{
|
||||
color: var(--el-text-color-primary) !important;
|
||||
|
|
@ -143,5 +150,9 @@ html.dark {
|
|||
color: white!important;
|
||||
}
|
||||
|
||||
.el-table__header th {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
.el-table__header th {
|
||||
font-weight: bold;
|
||||
color: #252525;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
|
@ -2,5 +2,6 @@
|
|||
@import './sidebar.scss';
|
||||
@import './transition.scss';
|
||||
@import "./common.scss";
|
||||
@import "./element.scss";
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,19 @@
|
|||
// position: absolute;
|
||||
// z-index: -1;
|
||||
//}
|
||||
.breadcrumb-enter-active,
|
||||
.breadcrumb-leave-active {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.breadcrumb-enter-from,
|
||||
.breadcrumb-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(10px);
|
||||
}
|
||||
.breadcrumb-leave-active {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
|
||||
.fade-transform-leave-active,
|
||||
|
|
|
|||
|
|
@ -479,3 +479,16 @@ export function getLightColor(color: string, level: number) {
|
|||
for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]);
|
||||
return rgbToHex(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
|
||||
export function getTimeState() {
|
||||
// 获取当前时间
|
||||
let timeNow = new Date();
|
||||
// 获取当前小时
|
||||
let hours = timeNow.getHours();
|
||||
// 判断当前时间段
|
||||
if (hours >= 6 && hours <= 10) return `早上好 ⛅`;
|
||||
if (hours >= 10 && hours <= 14) return `中午好 🌞`;
|
||||
if (hours >= 14 && hours <= 18) return `下午好 🌞`;
|
||||
if (hours >= 18 && hours <= 24) return `晚上好 🌛`;
|
||||
if (hours >= 0 && hours <= 6) return `凌晨好 🌛`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<u-container-layout>
|
||||
<div style="margin-bottom: 15px; display: flex; align-items: center">
|
||||
<div class="header">
|
||||
<el-input
|
||||
v-model="input"
|
||||
placeholder="请输入文件名"
|
||||
|
|
@ -22,11 +22,13 @@
|
|||
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出 Excel
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="list" style="width: 100%" border>
|
||||
<template v-for="(item, index) in column" :key="index">
|
||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||
</template>
|
||||
</el-table>
|
||||
<div class="footer">
|
||||
<el-table :data="list" border class="table">
|
||||
<template v-for="(item, index) in column" :key="index">
|
||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
</u-container-layout>
|
||||
</template>
|
||||
|
||||
|
|
@ -100,4 +102,22 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.footer{
|
||||
flex: 1;
|
||||
position: relative;
|
||||
.table{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<u-container-layout>
|
||||
<div style="margin-bottom: 15px; display: flex; align-items: center">
|
||||
<div class=".header">
|
||||
<el-input
|
||||
v-model="input"
|
||||
placeholder="请输入文件名"
|
||||
|
|
@ -10,11 +10,13 @@
|
|||
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出样式 Excel
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="list" style="width: 100%" border>
|
||||
<template v-for="(item, index) in column" :key="index">
|
||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||
</template>
|
||||
</el-table>
|
||||
<div class="footer">
|
||||
<el-table :data="list" class="table" border>
|
||||
<template v-for="(item, index) in column" :key="index">
|
||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
</u-container-layout>
|
||||
</template>
|
||||
|
||||
|
|
@ -88,4 +90,22 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
<style lang="scss" scoped>
|
||||
.header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.footer{
|
||||
flex: 1;
|
||||
position: relative;
|
||||
.table{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -63,9 +63,12 @@
|
|||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ElNotification } from "element-plus";
|
||||
import { useRouter } from 'vue-router'
|
||||
import {useUserStore} from "@/store/modules/user"
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {getTimeState} from '@/utils/index'
|
||||
|
||||
const ruleFormRef = ref<FormInstance>()
|
||||
const router = useRouter()
|
||||
const UserStore = useUserStore()
|
||||
|
|
@ -108,14 +111,18 @@
|
|||
const submitForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.validate(async (valid) => {
|
||||
console.log('valid==', valid)
|
||||
if (valid) {
|
||||
// 登录
|
||||
await UserStore.login( ruleForm)
|
||||
ElMessage.success('登录成功')
|
||||
router.push({
|
||||
path: '/',
|
||||
})
|
||||
ElNotification({
|
||||
title: getTimeState(),
|
||||
message: "欢迎登录 Vue Admin Perfect",
|
||||
type: "success",
|
||||
duration: 3000
|
||||
});
|
||||
} else {
|
||||
console.log('error submit!')
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<u-container-layout style="min-height: 300px">
|
||||
<el-button @contextmenu.prevent="rightClick">右键菜单</el-button>
|
||||
<el-button @contextmenu.prevent="rightClick" style="width: 200px">右键菜单</el-button>
|
||||
<u-right-click-menu :left="clientX" :top="clientY" @ok="operatingRightAction" :data="data" />
|
||||
</u-container-layout>
|
||||
</template>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import URightClickMenu from '@/components/u-rightClickMenu/index.vue'
|
||||
|
||||
const clientX = ref(0)
|
||||
const clientY = ref(0)
|
||||
import { useRouter } from 'vue-router'
|
||||
|
|
|
|||
Loading…
Reference in New Issue