feat:vue-elemet-admin升级改造
This commit is contained in:
parent
0ec8710e6f
commit
e983182fdb
|
|
@ -10,6 +10,7 @@
|
|||
"axios": "^0.24.0",
|
||||
"element-plus": "^1.2.0-beta.3",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"screenfull": "^6.0.0",
|
||||
"vue": "^3.2.16",
|
||||
"vue-router": "^4.0.12",
|
||||
"vuex": "^4.0.2"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -1,23 +1,33 @@
|
|||
<template>
|
||||
<section class="app-main">
|
||||
<transition name="fade-transform" mode="out-in">
|
||||
<router-view :key="key"/>
|
||||
</transition>
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition name="router-fade" mode="out-in">
|
||||
<keep-alive :include="cachedViews()">
|
||||
<component :is="Component" :key="key"/>
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {useRoute} from "vue-router";
|
||||
<script lang="ts">
|
||||
import {defineComponent} from "vue";
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
const cachedViews = () => {
|
||||
return store.state.tagsView.cachedViews
|
||||
}
|
||||
const key = () => {
|
||||
return route.path
|
||||
}
|
||||
return {
|
||||
cachedViews,
|
||||
key
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,33 @@
|
|||
<template>
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
<el-dropdown-menu slot="dropdown" class="user-dropdown">
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>
|
||||
Home
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>Dashboard</el-dropdown-item>
|
||||
</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>
|
||||
</a>
|
||||
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
|
||||
|
|
@ -30,18 +41,19 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {reactive,computed,toRefs} from "vue";
|
||||
import {useStore} from "@/store";
|
||||
import {useRoute,useRouter} from "vue-router"
|
||||
import Breadcrumb from '@/components/Breadcrumb/index.vue'
|
||||
import Hamburger from '@/components/Hamburger/index.vue'
|
||||
import Screenfull from '@/components/screenfull/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Hamburger
|
||||
Hamburger,
|
||||
Screenfull
|
||||
},
|
||||
setup() {
|
||||
const store = useStore()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
<script>
|
||||
import {computed, defineComponent} from "vue";
|
||||
import SidebarItem from './SidebarItem.vue'
|
||||
import SidebarLogo from './Logo.vue'
|
||||
import Logo from './Logo.vue'
|
||||
import variables from '@styles/variables.scss'
|
||||
import {useStore} from '@/store'
|
||||
import {useRoute} from 'vue-router'
|
||||
|
|
@ -31,7 +31,7 @@ import {useRoute} from 'vue-router'
|
|||
export default defineComponent({
|
||||
components: {
|
||||
SidebarItem,
|
||||
SidebarLogo
|
||||
Logo
|
||||
},
|
||||
setup() {
|
||||
const store = useStore()
|
||||
|
|
@ -39,6 +39,9 @@ export default defineComponent({
|
|||
const sidebar = computed(() => {
|
||||
return store.state.app.sidebar
|
||||
})
|
||||
const routes = computed(() => {
|
||||
return store.state.permission.routes
|
||||
})
|
||||
const showLogo = computed(() => {
|
||||
return store.state.settings.sidebarLogo
|
||||
})
|
||||
|
|
@ -56,7 +59,7 @@ export default defineComponent({
|
|||
|
||||
return {
|
||||
sidebar,
|
||||
route,
|
||||
routes,
|
||||
showLogo,
|
||||
variables,
|
||||
activeMenu,
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ export default defineComponent({
|
|||
const instance = getCurrentInstance()
|
||||
const currentRoute = useRoute()
|
||||
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]
|
||||
if (latestView && latestView.fullPath) {
|
||||
router.push(latestView.fullPath)
|
||||
|
|
@ -70,12 +70,12 @@ export default defineComponent({
|
|||
visible: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
selectedTag: {},
|
||||
affixTags: [],
|
||||
isActive: (route) => {
|
||||
selectedTag: {} as TagView,
|
||||
affixTags: [] as TagView[],
|
||||
isActive: (route:TagView) => {
|
||||
return route.path === currentRoute.path
|
||||
},
|
||||
isAffix: (tag) => {
|
||||
isAffix: (tag:TagView) => {
|
||||
return tag.meta && tag.meta.affix
|
||||
},
|
||||
refreshSelectedTag: (view: TagView) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<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"/>
|
||||
<div :class="{hasTagsView:needTagsView}" class="main-container">
|
||||
<div :class="{'fixed-header':fixedHeader}">
|
||||
|
|
@ -8,20 +8,23 @@
|
|||
<tags-view v-if="needTagsView"/>
|
||||
</div>
|
||||
<app-main/>
|
||||
<!--
|
||||
<right-panel v-if="showSettings">
|
||||
<settings/>
|
||||
</right-panel>
|
||||
<settings/>
|
||||
</right-panel>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import {computed, defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, toRefs} from "vue";
|
||||
import {AppMain,Navbar, Settings,Sidebar,TagsView } from './components'
|
||||
import resize from './mixin/ResizeHandler'
|
||||
import {computed, defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, toRefs, watch} from "vue";
|
||||
import {AppMain, Navbar, Settings, Sidebar, TagsView} from './components/index.ts'
|
||||
import {useStore} from "@store";
|
||||
|
||||
import {useRoute} from "vue-router";
|
||||
const {body} = document
|
||||
const WIDTH = 992
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Layout',
|
||||
|
|
@ -34,14 +37,50 @@ export default defineComponent({
|
|||
},
|
||||
setup() {
|
||||
const store = useStore()
|
||||
const {
|
||||
sidebar,
|
||||
device,
|
||||
resizeMounted,
|
||||
addEventListenerOnResize,
|
||||
removeEventListenerResize,
|
||||
watchRouter
|
||||
} = resize()
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const state = reactive({
|
||||
handleClickOutside: () => {
|
||||
|
|
@ -57,33 +96,33 @@ export default defineComponent({
|
|||
mobile: device === 'mobile'
|
||||
}
|
||||
})
|
||||
const showSettings=computed(()=>{
|
||||
const showSettings = computed(() => {
|
||||
return store.state.settings.showSettings
|
||||
})
|
||||
|
||||
const needTagsView=computed(()=>{
|
||||
const needTagsView = computed(() => {
|
||||
return store.state.settings.tagsView
|
||||
})
|
||||
|
||||
const fixedHeader=computed(()=>{
|
||||
const fixedHeader = computed(() => {
|
||||
return store.state.settings.fixedHeader
|
||||
})
|
||||
|
||||
watchRouter()
|
||||
|
||||
onBeforeMount(()=>{
|
||||
onBeforeMount(() => {
|
||||
addEventListenerOnResize()
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
onMounted(() => {
|
||||
resizeMounted()
|
||||
})
|
||||
|
||||
onBeforeUnmount(()=>{
|
||||
onBeforeUnmount(() => {
|
||||
removeEventListenerResize()
|
||||
})
|
||||
|
||||
return{
|
||||
return {
|
||||
classObj,
|
||||
sidebar,
|
||||
showSettings,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue