feat:vue-elemet-admin升级改造

This commit is contained in:
有来技术 2021-11-23 23:14:33 +08:00
parent 0ec8710e6f
commit e983182fdb
8 changed files with 200 additions and 109 deletions

View File

@ -10,6 +10,7 @@
"axios": "^0.24.0", "axios": "^0.24.0",
"element-plus": "^1.2.0-beta.3", "element-plus": "^1.2.0-beta.3",
"path-to-regexp": "^6.2.0", "path-to-regexp": "^6.2.0",
"screenfull": "^6.0.0",
"vue": "^3.2.16", "vue": "^3.2.16",
"vue-router": "^4.0.12", "vue-router": "^4.0.12",
"vuex": "^4.0.2" "vuex": "^4.0.2"

View File

@ -0,0 +1,88 @@
<template>
<div id="screenfull">
<div
v-if="isFullscreen"
@click="click"
>
<svg
class="icon"
aria-hidden="true"
font-size="40px"
>
<use xlink:href="#iconshiliangzhinengduixiang1" />
</svg>
</div>
<div
@click="click"
v-else
>
<svg
class="icon"
aria-hidden="true"
font-size="40px"
>
<use xlink:href="#iconshiliangzhinengduixiang1" />
</svg>
</div>
</div>
</template>
<script>
import screenfull from 'screenfull'
import { ElMessage } from 'element-plus'
import {defineComponent,onBeforeUnmount,onMounted,reactive,toRefs} from "vue";
export default defineComponent({
setup(){
const state =reactive({
isFullscreen: false,
click:()=>{
if (!screenfull.isEnabled) {
ElMessage({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle()
}
})
const change=()=>{
if(screenfull.isEnabled){
this.isFullscreen = screenfull.isFullscreen
}
}
onMounted(() => {
if (screenfull.isEnabled) {
screenfull.on('change', change)
}
})
onBeforeUnmount(() => {
if (screenfull.isEnabled) {
screenfull.off('change', change)
}
})
return {
...toRefs(state)
}
}
})
</script>
<style scoped>
.screenfull-svg {
display: inline-block;
cursor: pointer;
fill: #5a5e66;;
width: 20px;
height: 20px;
vertical-align: 10px;
}
</style>

View File

@ -1,23 +1,33 @@
<template> <template>
<section class="app-main"> <section class="app-main">
<transition name="fade-transform" mode="out-in"> <router-view v-slot="{ Component }">
<router-view :key="key"/> <transition name="router-fade" mode="out-in">
</transition> <keep-alive :include="cachedViews()">
<component :is="Component" :key="key"/>
</keep-alive>
</transition>
</router-view>
</section> </section>
</template> </template>
<script lang="ts">
import {useRoute} from "vue-router"; <script lang="ts">
import {defineComponent} from "vue"; import {defineComponent} from "vue";
import {useStore} from '@/store'
import {useRoute} from "vue-router";
export default defineComponent({ export default defineComponent({
setup() { setup() {
const store = useStore()
const route = useRoute() const route = useRoute()
const cachedViews = () => {
return store.state.tagsView.cachedViews
}
const key = () => { const key = () => {
return route.path return route.path
} }
return { return {
cachedViews,
key key
} }
} }

View File

@ -1,22 +1,33 @@
<template> <template>
<div class="navbar"> <div class="navbar">
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar"/> <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb class="breadcrumb-container"/> <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
<div class="right-menu"> <div class="right-menu">
<el-dropdown class="avatar-container" trigger="click"> <template v-if="device!=='mobile'">
<!-- <search id="header-search" class="right-menu-item" />
<error-log class="errLog-container right-menu-item hover-effect" />-->
<screenfull id="screenfull" class="right-menu-item hover-effect" />
<!-- <el-tooltip content="Global Size" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>-->
</template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
<i class="el-icon-caret-bottom"/> <i class="el-icon-caret-bottom" />
</div> </div>
<el-dropdown-menu slot="dropdown" class="user-dropdown"> <el-dropdown-menu slot="dropdown">
<router-link to="/"> <router-link to="/">
<el-dropdown-item> <el-dropdown-item>Dashboard</el-dropdown-item>
Home
</el-dropdown-item>
</router-link> </router-link>
<a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> <a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
<el-dropdown-item>Github</el-dropdown-item> <el-dropdown-item>Github</el-dropdown-item>
</a> </a>
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
@ -30,18 +41,19 @@
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import {reactive,computed,toRefs} from "vue"; import {reactive,computed,toRefs} from "vue";
import {useStore} from "@/store"; import {useStore} from "@/store";
import {useRoute,useRouter} from "vue-router" import {useRoute,useRouter} from "vue-router"
import Breadcrumb from '@/components/Breadcrumb/index.vue' import Breadcrumb from '@/components/Breadcrumb/index.vue'
import Hamburger from '@/components/Hamburger/index.vue' import Hamburger from '@/components/Hamburger/index.vue'
import Screenfull from '@/components/screenfull/index.vue'
export default { export default {
components: { components: {
Breadcrumb, Breadcrumb,
Hamburger Hamburger,
Screenfull
}, },
setup() { setup() {
const store = useStore() const store = useStore()

View File

@ -22,7 +22,7 @@
<script> <script>
import {computed, defineComponent} from "vue"; import {computed, defineComponent} from "vue";
import SidebarItem from './SidebarItem.vue' import SidebarItem from './SidebarItem.vue'
import SidebarLogo from './Logo.vue' import Logo from './Logo.vue'
import variables from '@styles/variables.scss' import variables from '@styles/variables.scss'
import {useStore} from '@/store' import {useStore} from '@/store'
import {useRoute} from 'vue-router' import {useRoute} from 'vue-router'
@ -31,7 +31,7 @@ import {useRoute} from 'vue-router'
export default defineComponent({ export default defineComponent({
components: { components: {
SidebarItem, SidebarItem,
SidebarLogo Logo
}, },
setup() { setup() {
const store = useStore() const store = useStore()
@ -39,6 +39,9 @@ export default defineComponent({
const sidebar = computed(() => { const sidebar = computed(() => {
return store.state.app.sidebar return store.state.app.sidebar
}) })
const routes = computed(() => {
return store.state.permission.routes
})
const showLogo = computed(() => { const showLogo = computed(() => {
return store.state.settings.sidebarLogo return store.state.settings.sidebarLogo
}) })
@ -56,7 +59,7 @@ export default defineComponent({
return { return {
sidebar, sidebar,
route, routes,
showLogo, showLogo,
variables, variables,
activeMenu, activeMenu,

View File

@ -51,9 +51,9 @@ export default defineComponent({
const instance = getCurrentInstance() const instance = getCurrentInstance()
const currentRoute = useRoute() const currentRoute = useRoute()
const scrollPaneRef = ref(null) const scrollPaneRef = ref(null)
const {ctx} = instance const {ctx} = instance as any
const toLastView=(visitedViews,view)=>{ const toLastView=(visitedViews:TagView[],view:TagView)=>{
const latestView = visitedViews.slice(-1)[0] const latestView = visitedViews.slice(-1)[0]
if (latestView && latestView.fullPath) { if (latestView && latestView.fullPath) {
router.push(latestView.fullPath) router.push(latestView.fullPath)
@ -70,12 +70,12 @@ export default defineComponent({
visible: false, visible: false,
top: 0, top: 0,
left: 0, left: 0,
selectedTag: {}, selectedTag: {} as TagView,
affixTags: [], affixTags: [] as TagView[],
isActive: (route) => { isActive: (route:TagView) => {
return route.path === currentRoute.path return route.path === currentRoute.path
}, },
isAffix: (tag) => { isAffix: (tag:TagView) => {
return tag.meta && tag.meta.affix return tag.meta && tag.meta.affix
}, },
refreshSelectedTag: (view: TagView) => { refreshSelectedTag: (view: TagView) => {

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="classObj" class="app-wrapper"> <div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> <div v-if="classObj.mobile==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar class="sidebar-container"/> <sidebar class="sidebar-container"/>
<div :class="{hasTagsView:needTagsView}" class="main-container"> <div :class="{hasTagsView:needTagsView}" class="main-container">
<div :class="{'fixed-header':fixedHeader}"> <div :class="{'fixed-header':fixedHeader}">
@ -8,20 +8,23 @@
<tags-view v-if="needTagsView"/> <tags-view v-if="needTagsView"/>
</div> </div>
<app-main/> <app-main/>
<!--
<right-panel v-if="showSettings"> <right-panel v-if="showSettings">
<settings/> <settings/>
</right-panel> </right-panel>
-->
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import {computed, defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, toRefs} from "vue"; import {computed, defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, toRefs, watch} from "vue";
import {AppMain,Navbar, Settings,Sidebar,TagsView } from './components' import {AppMain, Navbar, Settings, Sidebar, TagsView} from './components/index.ts'
import resize from './mixin/ResizeHandler'
import {useStore} from "@store"; import {useStore} from "@store";
import {useRoute} from "vue-router";
const {body} = document
const WIDTH = 992
export default defineComponent({ export default defineComponent({
name: 'Layout', name: 'Layout',
@ -34,14 +37,50 @@ export default defineComponent({
}, },
setup() { setup() {
const store = useStore() const store = useStore()
const {
sidebar, const device = computed(() => {
device, return store.state.app.device
resizeMounted, })
addEventListenerOnResize,
removeEventListenerResize, const sidebar = computed(() => {
watchRouter return store.state.app.sidebar
} = resize() })
const isMobile = () => {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
}
const resizeHandler = () => {
if (!document.hidden) {
store.dispatch('app/toggleDevice', isMobile() ? 'mobile' : 'desktop')
if (isMobile()) {
store.dispatch('app/closeSideBar', {withoutAnimation: true})
}
}
}
const resizeMounted = () => {
if (isMobile()) {
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', {withoutAnimation: true})
}
}
const addEventListenerOnResize = () => {
window.addEventListener('resize', resizeHandler)
}
const removeEventListenerResize = () => {
window.removeEventListener('resize', resizeHandler)
}
const currentRoute = useRoute()
const watchRouter = watch(() => currentRoute.name, () => {
if (store.state.app.device === 'mobile' && store.state.app.sidebar.opened) {
store.dispatch('app/closeSideBar', false)
}
})
const state = reactive({ const state = reactive({
handleClickOutside: () => { handleClickOutside: () => {
@ -57,33 +96,33 @@ export default defineComponent({
mobile: device === 'mobile' mobile: device === 'mobile'
} }
}) })
const showSettings=computed(()=>{ const showSettings = computed(() => {
return store.state.settings.showSettings return store.state.settings.showSettings
}) })
const needTagsView=computed(()=>{ const needTagsView = computed(() => {
return store.state.settings.tagsView return store.state.settings.tagsView
}) })
const fixedHeader=computed(()=>{ const fixedHeader = computed(() => {
return store.state.settings.fixedHeader return store.state.settings.fixedHeader
}) })
watchRouter() watchRouter()
onBeforeMount(()=>{ onBeforeMount(() => {
addEventListenerOnResize() addEventListenerOnResize()
}) })
onMounted(()=>{ onMounted(() => {
resizeMounted() resizeMounted()
}) })
onBeforeUnmount(()=>{ onBeforeUnmount(() => {
removeEventListenerResize() removeEventListenerResize()
}) })
return{ return {
classObj, classObj,
sidebar, sidebar,
showSettings, showSettings,

View File

@ -1,62 +0,0 @@
import {useStore} from '@/store'
import {computed, watch} from "vue";
import { useRoute } from 'vue-router'
const store = useStore()
const {body} = document
const WIDTH = 992 // refer to Bootstrap's responsive design
export default function () {
const device = computed(() => {
return store.state.app.device
})
const sidebar = computed(() => {
return store.state.app.sidebar
})
const isMobile = () => {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
}
const resizeHandler = () => {
if (!document.hidden) {
store.dispatch('app/toggleDevice', isMobile() ? 'mobile' : 'desktop')
if (isMobile()) {
store.dispatch('app/closeSideBar', {withoutAnimation: true})
}
}
}
const resizeMounted = () => {
if(isMobile()){
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', {withoutAnimation: true})
}
}
const addEventListenerOnResize = () => {
window.addEventListener('resize', resizeHandler)
}
const removeEventListenerResize = () => {
window.removeEventListener('resize', resizeHandler)
}
const currentRoute = useRoute()
const watchRouter = watch(() => currentRoute.name, () => {
if (store.state.app.device === 'mobile' && store.state.app.sidebar.opened) {
store.dispatch('app/closeSideBar', false)
}
})
return {
device,
sidebar,
resizeMounted,
addEventListenerOnResize,
removeEventListenerResize,
watchRouter
}
}