Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
web-template
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张伯涛
web-template
Commits
b7cbfd82
Commit
b7cbfd82
authored
Aug 31, 2022
by
张伯涛
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
web端去除左侧目录结构以及修改控制台报错
parent
c57de5f5
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
746 additions
and
1280 deletions
+746
-1280
FixiOSBug.js
src/layout/components/Sidebar/FixiOSBug.js
+26
-26
Item.vue
src/layout/components/Sidebar/Item.vue
+27
-27
Link.vue
src/layout/components/Sidebar/Link.vue
+41
-41
Logo.vue
src/layout/components/Sidebar/Logo.vue
+75
-75
SidebarItem.vue
src/layout/components/Sidebar/SidebarItem.vue
+89
-89
index.vue
src/layout/components/Sidebar/index.vue
+52
-52
ScrollPane.vue
src/layout/components/TagsView/ScrollPane.vue
+85
-85
index.vue
src/layout/components/TagsView/index.vue
+302
-302
header.vue
src/layout/components/header.vue
+30
-30
index.vue
src/layout/index.vue
+1
-1
sidebar.scss
src/styles/sidebar.scss
+1
-1
index.vue
src/views/home/index.vue
+15
-0
equipment.vue
src/views/overView/dashboard/equipment.vue
+0
-464
test.vue
src/views/test/test.vue
+0
-85
vue.config.js
vue.config.js
+2
-2
No files found.
src/layout/components/Sidebar/FixiOSBug.js
View file @
b7cbfd82
export
default
{
computed
:
{
device
()
{
return
this
.
$store
.
state
.
app
.
device
}
},
mounted
()
{
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
this
.
fixBugIniOS
()
},
methods
:
{
fixBugIniOS
()
{
const
$subMenu
=
this
.
$refs
.
subMenu
if
(
$subMenu
)
{
const
handleMouseleave
=
$subMenu
.
handleMouseleave
$subMenu
.
handleMouseleave
=
(
e
)
=>
{
if
(
this
.
device
===
'mobile'
)
{
return
}
handleMouseleave
(
e
)
}
}
}
}
}
//
export default {
//
computed: {
//
device() {
//
return this.$store.state.app.device
//
}
//
},
//
mounted() {
//
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
//
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
//
this.fixBugIniOS()
//
},
//
methods: {
//
fixBugIniOS() {
//
const $subMenu = this.$refs.subMenu
//
if ($subMenu) {
//
const handleMouseleave = $subMenu.handleMouseleave
//
$subMenu.handleMouseleave = (e) => {
//
if (this.device === 'mobile') {
//
return
//
}
//
handleMouseleave(e)
//
}
//
}
//
}
//
}
//
}
src/layout/components/Sidebar/Item.vue
View file @
b7cbfd82
<
script
>
export
default
{
name
:
'MenuItem'
,
functional
:
true
,
props
:
{
icon
:
{
type
:
String
,
default
:
''
},
title
:
{
type
:
String
,
default
:
''
}
},
render
(
h
,
context
)
{
const
{
icon
,
title
}
=
context
.
props
const
vnodes
=
[]
<
!--<script>--
>
<!--export default {-->
<!-- name: 'MenuItem',-->
<!-- functional: true,-->
<!-- props: {-->
<!-- icon: {-->
<!-- type: String,-->
<!-- default: ''-->
<!-- },-->
<!-- title: {-->
<!-- type: String,-->
<!-- default: ''-->
<!-- }-->
<!-- },-->
<!-- render(h, context) {-->
<!-- const { icon, title } = context.props-->
<!-- const vnodes = []-->
if
(
icon
)
{
vnodes
.
push
(
<
svg
-
icon
icon
-
class
=
{
icon
}
/>
)
}
<!-- if (icon) {-->
<!-- vnodes.push(<svg-icon icon-class={icon}/>)-->
<!-- }-->
if
(
title
)
{
vnodes
.
push
(
<
span
slot
=
'title'
>
{(
title
)}
<
/span>
)
}
return
vnodes
}
}
<
/
script
>
<!-- if (title) {-->
<!-- vnodes.push(<span slot='title'>{(title)}</span>)-->
<!-- }-->
<!-- return vnodes-->
<!-- }-->
<!--}-->
<
!--</script>--
>
src/layout/components/Sidebar/Link.vue
View file @
b7cbfd82
<
template
>
<component
:is=
"type"
v-bind=
"linkProps(to)"
>
<slot
/
>
</component
>
<
/
template
>
<
!--<template>--
>
<!-- <component :is="type" v-bind="linkProps(to)">--
>
<!-- <slot />--
>
<!-- </component>--
>
<
!--</template>--
>
<
script
>
import
{
isExternal
}
from
'@/utils/validate'
<
!--<script>--
>
<!--import { isExternal } from '@/utils/validate'-->
export
default
{
props
:
{
to
:
{
type
:
String
,
required
:
true
}
},
computed
:
{
isExternal
()
{
return
isExternal
(
this
.
to
)
},
type
()
{
if
(
this
.
isExternal
)
{
return
'a'
}
return
'router-link'
}
},
methods
:
{
linkProps
(
to
)
{
if
(
this
.
isExternal
)
{
return
{
href
:
to
,
target
:
'_blank'
,
rel
:
'noopener'
}
}
return
{
to
:
to
}
}
}
}
<
/
script
>
<!--export default {-->
<!-- props: {-->
<!-- to: {-->
<!-- type: String,-->
<!-- required: true-->
<!-- }-->
<!-- },-->
<!-- computed: {-->
<!-- isExternal() {-->
<!-- return isExternal(this.to)-->
<!-- },-->
<!-- type() {-->
<!-- if (this.isExternal) {-->
<!-- return 'a'-->
<!-- }-->
<!-- return 'router-link'-->
<!-- }-->
<!-- },-->
<!-- methods: {-->
<!-- linkProps(to) {-->
<!-- if (this.isExternal) {-->
<!-- return {-->
<!-- href: to,-->
<!-- target: '_blank',-->
<!-- rel: 'noopener'-->
<!-- }-->
<!-- }-->
<!-- return {-->
<!-- to: to-->
<!-- }-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</script>--
>
src/layout/components/Sidebar/Logo.vue
View file @
b7cbfd82
<
template
>
<div
class=
"sidebar-logo-container"
:class=
"
{'collapse':collapse}"
>
<transition
name=
"sidebarLogoFade"
>
<router-link
v-if=
"collapse"
key=
"collapse"
class=
"sidebar-logo-link"
to=
"/"
>
<img
v-if=
"logo"
:src=
"logo"
class=
"sidebar-logo"
>
<h1
v-else
class=
"sidebar-title"
>
{{
title
}}
</h1
>
</router-link
>
<router-link
v-else
key=
"expand"
class=
"sidebar-logo-link"
to=
"/"
>
<img
v-if=
"logo"
:src=
"logo"
class=
"sidebar-logo"
>
<h1
class=
"sidebar-title"
>
{{
title
}}
</h1
>
</router-link
>
</transition
>
</div
>
<
/
template
>
<
!--<template>--
>
<!-- <div class="sidebar-logo-container" :class="{'collapse':collapse}">--
>
<!-- <transition name="sidebarLogoFade">--
>
<!-- <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">--
>
<!-- <img v-if="logo" :src="logo" class="sidebar-logo">--
>
<!-- <h1 v-else class="sidebar-title">{{ title }} </h1>--
>
<!-- </router-link>--
>
<!-- <router-link v-else key="expand" class="sidebar-logo-link" to="/">--
>
<!-- <img v-if="logo" :src="logo" class="sidebar-logo">--
>
<!-- <h1 class="sidebar-title">{{ title }} </h1>--
>
<!-- </router-link>--
>
<!-- </transition>--
>
<!-- </div>--
>
<
!--</template>--
>
<
script
>
export
default
{
name
:
'SidebarLogo'
,
props
:
{
collapse
:
{
type
:
Boolean
,
required
:
true
}
},
data
()
{
return
{
title
:
'信息化管理系统'
,
logo
:
require
(
'@/assets/image/logo.png'
)
}
}
}
<
/
script
>
<
!--<script>--
>
<!--export default {-->
<!-- name: 'SidebarLogo',-->
<!-- props: {-->
<!-- collapse: {-->
<!-- type: Boolean,-->
<!-- required: true-->
<!-- }-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- title: '信息化管理系统',-->
<!-- logo: require('@/assets/image/logo.png')-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</script>--
>
<
style
lang=
"scss"
scoped
>
@import
"~@/styles/variables.scss"
;
.sidebarLogoFade-enter-active
{
transition
:
opacity
1
.5s
;
}
<
!--<style lang="scss" scoped>--
>
<!--@import "~@/styles/variables.scss";-->
<!--.sidebarLogoFade-enter-active {-->
<!-- transition: opacity 1.5s;-->
<!--}-->
.sidebarLogoFade-enter
,
.sidebarLogoFade-leave-to
{
opacity
:
0
;
}
<!--.sidebarLogoFade-enter,-->
<!--.sidebarLogoFade-leave-to {-->
<!-- opacity: 0;-->
<!--}-->
.sidebar-logo-container
{
position
:
relative
;
width
:
100%
;
height
:
50px
;
line-height
:
50px
;
background
:
$menuBg
;
padding-left
:
11px
;
overflow
:
hidden
;
<!--.sidebar-logo-container {-->
<!-- position: relative;-->
<!-- width: 100%;-->
<!-- height: 50px;-->
<!-- line-height: 50px;-->
<!-- background: $menuBg;-->
<!-- padding-left: 11px;-->
<!-- overflow: hidden;-->
&
.sidebar-logo-link
{
height
:
100%
;
width
:
100%
;
<!-- & .sidebar-logo-link {-->
<!-- height: 100%;-->
<!-- width: 100%;-->
&
.sidebar-logo
{
width
:
32px
;
height
:
32px
;
vertical-align
:
middle
;
margin-right
:
12px
;
}
<!-- & .sidebar-logo {-->
<!-- width: 32px;-->
<!-- height: 32px;-->
<!-- vertical-align: middle;-->
<!-- margin-right: 12px;-->
<!-- }-->
&
.sidebar-title
{
display
:
inline-block
;
margin
:
0
;
color
:
#fff
;
font-weight
:
600
;
line-height
:
50px
;
font-size
:
16px
;
font-family
:
Avenir
,
Helvetica
Neue
,
Arial
,
Helvetica
,
sans-serif
;
vertical-align
:
middle
;
}
}
<!-- & .sidebar-title {-->
<!-- display: inline-block;-->
<!-- margin: 0;-->
<!-- color: #fff;-->
<!-- font-weight: 600;-->
<!-- line-height: 50px;-->
<!-- font-size: 16px;-->
<!-- font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;-->
<!-- vertical-align: middle;-->
<!-- }-->
<!-- }-->
&
.collapse
{
.sidebar-logo
{
margin-right
:
0px
;
}
}
}
<
/
style
>
<!-- &.collapse {-->
<!-- .sidebar-logo {-->
<!-- margin-right: 0px;-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</style>--
>
src/layout/components/Sidebar/SidebarItem.vue
View file @
b7cbfd82
<
template
>
<div
v-if=
"!item.hidden"
>
<template
v-if=
"item.showFather !== 'true' && hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
>
<app-link
v-if=
"onlyOneChild.meta"
:to=
"resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index=
"resolvePath(onlyOneChild.path)"
:class=
"
{'submenu-title-noDropdown':!isNest}"
>
<item
:icon=
"onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
:title=
"onlyOneChild.meta.title"
/
>
</el-menu-item
>
</app-link
>
</
template
>
<
!--<template>--
>
<!-- <div v-if="!item.hidden">--
>
<!-- <template v-if="item.showFather !== 'true' && hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">--
>
<!-- <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">--
>
<!-- <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">--
>
<!-- <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />--
>
<!-- </el-menu-item>--
>
<!-- </app-link>--
>
<!-- </template>--
>
<el-submenu
v-else
ref=
"subMenu"
:index=
"resolvePath(item.path)"
popper-append-to-body
>
<
template
slot=
"title"
>
<item
v-if=
"item.meta"
:icon=
"item.meta && item.meta.icon"
:title=
"item.meta.title"
/
>
</
template
>
<sidebar-item
v-for=
"child in item.children"
:key=
"child.path"
:is-nest=
"true"
:item=
"child"
:base-path=
"resolvePath(child.path)"
class=
"nest-menu"
/
>
</el-submenu
>
</div
>
<
/template
>
<!-- <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>--
>
<!-- <template slot="title">--
>
<!-- <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />--
>
<!-- </template>--
>
<!-- <sidebar-item-->
<!-- v-for="child in item.children"-->
<!-- :key="child.path"-->
<!-- :is-nest="true"-->
<!-- :item="child"-->
<!-- :base-path="resolvePath(child.path)"-->
<!-- class="nest-menu"-->
<!-- />--
>
<!-- </el-submenu>--
>
<!-- </div>--
>
<
!--</template>--
>
<
script
>
import
path
from
'path'
import
{
isExternal
}
from
'@/utils/validate'
import
Item
from
'./Item'
import
AppLink
from
'./Link'
import
FixiOSBug
from
'./FixiOSBug'
<
!--<script>--
>
<!--import path from 'path'-->
<!--import { isExternal } from '@/utils/validate'-->
<!--import Item from './Item'-->
<!--import AppLink from './Link'-->
<!--import FixiOSBug from './FixiOSBug'-->
export
default
{
name
:
'SidebarItem'
,
components
:
{
Item
,
AppLink
},
mixins
:
[
FixiOSBug
],
props
:
{
// route object
item
:
{
type
:
Object
,
required
:
true
},
isNest
:
{
type
:
Boolean
,
default
:
false
},
basePath
:
{
type
:
String
,
default
:
''
}
},
data
()
{
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this
.
onlyOneChild
=
null
return
{}
},
methods
:
{
hasOneShowingChild
(
children
=
[],
parent
)
{
const
showingChildren
=
children
.
filter
(
item
=>
{
if
(
item
.
hidden
)
{
return
false
}
else
{
// Temp set(will be used if only has one showing child)
this
.
onlyOneChild
=
item
return
true
}
})
<!--export default {-->
<!-- name: 'SidebarItem',-->
<!-- components: { Item, AppLink },-->
<!-- mixins: [FixiOSBug],-->
<!-- props: {-->
<!-- // route object-->
<!-- item: {-->
<!-- type: Object,-->
<!-- required: true-->
<!-- },-->
<!-- isNest: {-->
<!-- type: Boolean,-->
<!-- default: false-->
<!-- },-->
<!-- basePath: {-->
<!-- type: String,-->
<!-- default: ''-->
<!-- }-->
<!-- },-->
<!-- data() {-->
<!-- // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237-->
<!-- // TODO: refactor with render function-->
<!-- this.onlyOneChild = null-->
<!-- return {}-->
<!-- },-->
<!-- methods: {-->
<!-- hasOneShowingChild(children = [], parent) {-->
<!-- const showingChildren = children.filter(item => {-->
<!-- if (item.hidden) {-->
<!-- return false-->
<!-- } else {-->
<!-- // Temp set(will be used if only has one showing child)-->
<!-- this.onlyOneChild = item-->
<!-- return true-->
<!-- }-->
<!-- })-->
// When there is only one child router, the child router is displayed by default
if
(
showingChildren
.
length
===
1
)
{
return
true
}
<!-- // When there is only one child router, the child router is displayed by default-->
<!-- if (showingChildren.length === 1) {-->
<!-- return true-->
<!-- }-->
// Show parent if there are no child router to display
if
(
showingChildren
.
length
===
0
)
{
this
.
onlyOneChild
=
{
...
parent
,
path
:
''
,
noShowingChildren
:
true
}
return
true
}
<!-- // Show parent if there are no child router to display-->
<!-- if (showingChildren.length === 0) {-->
<!-- this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }-->
<!-- return true-->
<!-- }-->
return
false
},
resolvePath
(
routePath
)
{
if
(
isExternal
(
routePath
))
{
return
routePath
}
if
(
isExternal
(
this
.
basePath
))
{
return
this
.
basePath
}
return
path
.
resolve
(
this
.
basePath
,
routePath
)
}
}
}
<
/
script
>
<!-- return false-->
<!-- },-->
<!-- resolvePath(routePath) {-->
<!-- if (isExternal(routePath)) {-->
<!-- return routePath-->
<!-- }-->
<!-- if (isExternal(this.basePath)) {-->
<!-- return this.basePath-->
<!-- }-->
<!-- return path.resolve(this.basePath, routePath)-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</script>--
>
src/layout/components/Sidebar/index.vue
View file @
b7cbfd82
<
template
>
<div
:class=
"
{'has-logo':showLogo}"
>
<logo
v-if=
"true"
:collapse=
"isCollapse"
/
>
<el-scrollbar
wrap-class=
"scrollbar-wrapper"
>
<el-menu
:default-active=
"activeMenu"
:collapse=
"isCollapse"
:background-color=
"variables.menuBg"
:text-color=
"variables.menuText"
:unique-opened=
"true"
:active-text-color=
"variables.menuActiveText"
:collapse-transition=
"false"
mode=
"vertical"
>
<sidebar-item
v-for=
"route in permission_routes"
:key=
"route.path"
:item=
"route"
:base-path=
"route.path"
/
>
</el-menu
>
</el-scrollbar
>
</div
>
<
/
template
>
<
!--<template>--
>
<!-- <div :class="{'has-logo':showLogo}">--
>
<!-- <logo v-if="true" :collapse="isCollapse" />--
>
<!-- <el-scrollbar wrap-class="scrollbar-wrapper">--
>
<!-- <el-menu-->
<!-- :default-active="activeMenu"-->
<!-- :collapse="isCollapse"-->
<!-- :background-color="variables.menuBg"-->
<!-- :text-color="variables.menuText"-->
<!-- :unique-opened="true"-->
<!-- :active-text-color="variables.menuActiveText"-->
<!-- :collapse-transition="false"-->
<!-- mode="vertical"-->
<!-- >--
>
<!-- <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />--
>
<!-- </el-menu>--
>
<!-- </el-scrollbar>--
>
<!-- </div>--
>
<
!--</template>--
>
<
script
>
import
{
mapGetters
}
from
'vuex'
import
Logo
from
'./Logo'
import
SidebarItem
from
'./SidebarItem'
import
variables
from
'@/styles/variables.scss'
<
!--<script>--
>
<!--import { mapGetters } from 'vuex'-->
<!--import Logo from './Logo'-->
<!--import SidebarItem from './SidebarItem'-->
<!--import variables from '@/styles/variables.scss'-->
export
default
{
components
:
{
SidebarItem
,
Logo
},
computed
:
{
...
mapGetters
([
'permission_routes'
,
'sidebar'
]),
activeMenu
()
{
const
route
=
this
.
$route
const
{
meta
,
path
}
=
route
// if set path, the sidebar will highlight the path you set
if
(
meta
.
activeMenu
)
{
return
meta
.
activeMenu
}
return
path
},
showLogo
()
{
return
this
.
$store
.
state
.
settings
.
sidebarLogo
},
variables
()
{
return
variables
},
isCollapse
()
{
return
!
this
.
sidebar
.
opened
}
}
}
<
/
script
>
<!--export default {-->
<!-- components: { SidebarItem, Logo },-->
<!-- computed: {-->
<!-- ...mapGetters([-->
<!-- 'permission_routes',-->
<!-- 'sidebar'-->
<!-- ]),-->
<!-- activeMenu() {-->
<!-- const route = this.$route-->
<!-- const { meta, path } = route-->
<!-- // if set path, the sidebar will highlight the path you set-->
<!-- if (meta.activeMenu) {-->
<!-- return meta.activeMenu-->
<!-- }-->
<!-- return path-->
<!-- },-->
<!-- showLogo() {-->
<!-- return this.$store.state.settings.sidebarLogo-->
<!-- },-->
<!-- variables() {-->
<!-- return variables-->
<!-- },-->
<!-- isCollapse() {-->
<!-- return !this.sidebar.opened-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</script>--
>
src/layout/components/TagsView/ScrollPane.vue
View file @
b7cbfd82
<
template
>
<el-scrollbar
ref=
"scrollContainer"
:vertical=
"false"
class=
"scroll-container"
@
wheel
.
native
.
prevent=
"handleScroll"
>
<slot
/
>
</el-scrollbar
>
<
/
template
>
<
!--<template>--
>
<!-- <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">--
>
<!-- <slot />--
>
<!-- </el-scrollbar>--
>
<
!--</template>--
>
<
script
>
const
tagAndTagSpacing
=
4
// tagAndTagSpacing
<
!--<script>--
>
<!--const tagAndTagSpacing = 4 // tagAndTagSpacing-->
export
default
{
name
:
'ScrollPane'
,
data
()
{
return
{
left
:
0
}
},
computed
:
{
scrollWrapper
()
{
return
this
.
$refs
.
scrollContainer
.
$refs
.
wrap
}
},
mounted
()
{
this
.
scrollWrapper
.
addEventListener
(
'scroll'
,
this
.
emitScroll
,
true
)
},
beforeDestroy
()
{
this
.
scrollWrapper
.
removeEventListener
(
'scroll'
,
this
.
emitScroll
)
},
methods
:
{
handleScroll
(
e
)
{
const
eventDelta
=
e
.
wheelDelta
||
-
e
.
deltaY
*
40
const
$scrollWrapper
=
this
.
scrollWrapper
$scrollWrapper
.
scrollLeft
=
$scrollWrapper
.
scrollLeft
+
eventDelta
/
4
},
emitScroll
()
{
this
.
$emit
(
'scroll'
)
},
moveToTarget
(
currentTag
)
{
const
$container
=
this
.
$refs
.
scrollContainer
.
$el
const
$containerWidth
=
$container
.
offsetWidth
const
$scrollWrapper
=
this
.
scrollWrapper
const
tagList
=
this
.
$parent
.
$refs
.
tag
<!--export default {-->
<!-- name: 'ScrollPane',-->
<!-- data() {-->
<!-- return {-->
<!-- left: 0-->
<!-- }-->
<!-- },-->
<!-- computed: {-->
<!-- scrollWrapper() {-->
<!-- return this.$refs.scrollContainer.$refs.wrap-->
<!-- }-->
<!-- },-->
<!-- mounted() {-->
<!-- this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)-->
<!-- },-->
<!-- beforeDestroy() {-->
<!-- this.scrollWrapper.removeEventListener('scroll', this.emitScroll)-->
<!-- },-->
<!-- methods: {-->
<!-- handleScroll(e) {-->
<!-- const eventDelta = e.wheelDelta || -e.deltaY * 40-->
<!-- const $scrollWrapper = this.scrollWrapper-->
<!-- $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4-->
<!-- },-->
<!-- emitScroll() {-->
<!-- this.$emit('scroll')-->
<!-- },-->
<!-- moveToTarget(currentTag) {-->
<!-- const $container = this.$refs.scrollContainer.$el-->
<!-- const $containerWidth = $container.offsetWidth-->
<!-- const $scrollWrapper = this.scrollWrapper-->
<!-- const tagList = this.$parent.$refs.tag-->
let
firstTag
=
null
let
lastTag
=
null
<!-- let firstTag = null-->
<!-- let lastTag = null-->
// find first tag and last tag
if
(
tagList
.
length
>
0
)
{
firstTag
=
tagList
[
0
]
lastTag
=
tagList
[
tagList
.
length
-
1
]
}
<!-- // find first tag and last tag-->
<!-- if (tagList.length > 0) {-->
<!-- firstTag = tagList[0]-->
<!-- lastTag = tagList[tagList.length - 1]-->
<!-- }-->
if
(
firstTag
===
currentTag
)
{
$scrollWrapper
.
scrollLeft
=
0
}
else
if
(
lastTag
===
currentTag
)
{
$scrollWrapper
.
scrollLeft
=
$scrollWrapper
.
scrollWidth
-
$containerWidth
}
else
{
// find preTag and nextTag
const
currentIndex
=
tagList
.
findIndex
(
item
=>
item
===
currentTag
)
const
prevTag
=
tagList
[
currentIndex
-
1
]
const
nextTag
=
tagList
[
currentIndex
+
1
]
<!-- if (firstTag === currentTag) {-->
<!-- $scrollWrapper.scrollLeft = 0-->
<!-- } else if (lastTag === currentTag) {-->
<!-- $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth-->
<!-- } else {-->
<!-- // find preTag and nextTag-->
<!-- const currentIndex = tagList.findIndex(item => item === currentTag)-->
<!-- const prevTag = tagList[currentIndex - 1]-->
<!-- const nextTag = tagList[currentIndex + 1]-->
// the tag's offsetLeft after of nextTag
const
afterNextTagOffsetLeft
=
nextTag
.
$el
.
offsetLeft
+
nextTag
.
$el
.
offsetWidth
+
tagAndTagSpacing
<!-- // the tag's offsetLeft after of nextTag-->
<!-- const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing-->
// the tag's offsetLeft before of prevTag
const
beforePrevTagOffsetLeft
=
prevTag
.
$el
.
offsetLeft
-
tagAndTagSpacing
<!-- // the tag's offsetLeft before of prevTag-->
<!-- const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing-->
if
(
afterNextTagOffsetLeft
>
$scrollWrapper
.
scrollLeft
+
$containerWidth
)
{
$scrollWrapper
.
scrollLeft
=
afterNextTagOffsetLeft
-
$containerWidth
}
else
if
(
beforePrevTagOffsetLeft
<
$scrollWrapper
.
scrollLeft
)
{
$scrollWrapper
.
scrollLeft
=
beforePrevTagOffsetLeft
}
}
}
}
}
<
/
script
>
<!-- if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {-->
<!-- $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth-->
<!-- } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {-->
<!-- $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft-->
<!-- }-->
<!-- }-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</script>--
>
<
style
lang=
"scss"
scoped
>
.scroll-container
{
white-space
:
nowrap
;
position
:
relative
;
overflow
:
hidden
;
width
:
100%
;
/
deep
/
{
.el-scrollbar__bar
{
bottom
:
0px
;
}
.el-scrollbar__wrap
{
height
:
49px
;
}
}
}
<
/
style
>
<
!--<style lang="scss" scoped>--
>
<!--.scroll-container {-->
<!-- white-space: nowrap;-->
<!-- position: relative;-->
<!-- overflow: hidden;-->
<!-- width: 100%;-->
<!-- /deep/ {-->
<!-- .el-scrollbar__bar {-->
<!-- bottom: 0px;-->
<!-- }-->
<!-- .el-scrollbar__wrap {-->
<!-- height: 49px;-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</style>--
>
src/layout/components/TagsView/index.vue
View file @
b7cbfd82
<
template
>
<div
id=
"tags-view-container"
class=
"tags-view-container"
>
<scroll-pane
ref=
"scrollPane"
class=
"tags-view-wrapper"
@
scroll=
"handleScroll"
>
<router-link
v-for=
"tag in visitedViews"
ref=
"tag"
:key=
"tag.path"
:class=
"isActive(tag)?'active':''"
:to=
"
{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="span"
class="tags-view-item"
:style="activeStyle(tag)"
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
{{
tag
.
title
}}
<span
v-if=
"!isAffix(tag)"
class=
"el-icon-close"
@
click
.
prevent
.
stop=
"closeSelectedTag(tag)"
/
>
</router-link
>
</scroll-pane
>
<ul
v-show=
"visible"
:style=
"
{left:left+'px',top:top+'px'}" class="contextmenu"
>
<li
@
click=
"refreshSelectedTag(selectedTag)"
>
刷新页面
</li
>
<li
v-if=
"!isAffix(selectedTag)"
@
click=
"closeSelectedTag(selectedTag)"
>
关闭当前
</li
>
<li
@
click=
"closeOthersTags"
>
关闭其他
</li
>
<li
@
click=
"closeAllTags(selectedTag)"
>
关闭所有
</li
>
</ul
>
</div
>
<
/
template
>
<
!--<template>--
>
<!-- <div id="tags-view-container" class="tags-view-container">--
>
<!-- <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">--
>
<!-- <router-link-->
<!-- v-for="tag in visitedViews"-->
<!-- ref="tag"-->
<!-- :key="tag.path"-->
<!-- :class="isActive(tag)?'active':''"-->
<!-- :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"-->
<!-- tag="span"-->
<!-- class="tags-view-item"-->
<!-- :style="activeStyle(tag)"-->
<!-- @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"-->
<!-- @contextmenu.prevent.native="openMenu(tag,$event)"-->
<!-- >--
>
<!-- {{ tag.title }}-->
<!-- <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />--
>
<!-- </router-link>--
>
<!-- </scroll-pane>--
>
<!-- <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">--
>
<!-- <li @click="refreshSelectedTag(selectedTag)">刷新页面</li>--
>
<!-- <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭当前</li>--
>
<!-- <li @click="closeOthersTags">关闭其他</li>--
>
<!-- <li @click="closeAllTags(selectedTag)">关闭所有</li>--
>
<!-- </ul>--
>
<!-- </div>--
>
<
!--</template>--
>
<
script
>
import
ScrollPane
from
'./ScrollPane'
import
path
from
'path'
<
!--<script>--
>
<!--import ScrollPane from './ScrollPane'-->
<!--import path from 'path'-->
export
default
{
name
:
'TagsView'
,
components
:
{
ScrollPane
},
data
()
{
return
{
visible
:
false
,
top
:
0
,
left
:
0
,
selectedTag
:
{},
affixTags
:
[]
}
},
computed
:
{
visitedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
visitedViews
},
routes
()
{
return
this
.
$store
.
state
.
permission
.
routes
},
theme
()
{
return
this
.
$store
.
state
.
settings
.
theme
}
},
watch
:
{
$route
()
{
this
.
addTags
()
this
.
moveToCurrentTag
()
},
visible
(
value
)
{
if
(
value
)
{
document
.
body
.
addEventListener
(
'click'
,
this
.
closeMenu
)
}
else
{
document
.
body
.
removeEventListener
(
'click'
,
this
.
closeMenu
)
}
}
},
mounted
()
{
this
.
initTags
()
this
.
addTags
()
},
methods
:
{
isActive
(
route
)
{
return
route
.
path
===
this
.
$route
.
path
},
activeStyle
(
tag
)
{
if
(
!
this
.
isActive
(
tag
))
return
{}
return
{
'background-color'
:
this
.
theme
,
'border-color'
:
this
.
theme
}
},
isAffix
(
tag
)
{
return
tag
.
meta
&&
tag
.
meta
.
affix
},
filterAffixTags
(
routes
,
basePath
=
'/'
)
{
let
tags
=
[]
routes
.
forEach
(
route
=>
{
if
(
route
.
meta
&&
route
.
meta
.
affix
)
{
const
tagPath
=
path
.
resolve
(
basePath
,
route
.
path
)
tags
.
push
({
fullPath
:
tagPath
,
path
:
tagPath
,
name
:
route
.
name
,
meta
:
{
...
route
.
meta
}
})
}
if
(
route
.
children
)
{
const
tempTags
=
this
.
filterAffixTags
(
route
.
children
,
route
.
path
)
if
(
tempTags
.
length
>=
1
)
{
tags
=
[...
tags
,
...
tempTags
]
}
}
})
return
tags
},
initTags
()
{
const
affixTags
=
this
.
affixTags
=
this
.
filterAffixTags
(
this
.
routes
)
for
(
const
tag
of
affixTags
)
{
// Must have tag name
if
(
tag
.
name
)
{
this
.
$store
.
dispatch
(
'tagsView/addVisitedView'
,
tag
)
}
}
},
addTags
()
{
const
{
name
}
=
this
.
$route
if
(
name
)
{
this
.
$store
.
dispatch
(
'tagsView/addView'
,
this
.
$route
)
}
if
(
this
.
visitedViews
.
length
>
10
)
{
this
.
closeSelectedTag
(
this
.
visitedViews
[
0
])
}
return
false
},
moveToCurrentTag
()
{
const
tags
=
this
.
$refs
.
tag
this
.
$nextTick
(()
=>
{
for
(
const
tag
of
tags
)
{
if
(
tag
.
to
.
path
===
this
.
$route
.
path
)
{
this
.
$refs
.
scrollPane
.
moveToTarget
(
tag
)
// when query is different then update
if
(
tag
.
to
.
fullPath
!==
this
.
$route
.
fullPath
)
{
this
.
$store
.
dispatch
(
'tagsView/updateVisitedView'
,
this
.
$route
)
}
break
}
}
})
},
refreshSelectedTag
(
view
)
{
this
.
$store
.
dispatch
(
'tagsView/delCachedView'
,
view
).
then
(()
=>
{
const
{
fullPath
}
=
view
this
.
$nextTick
(()
=>
{
this
.
$router
.
replace
({
path
:
'/redirect'
+
fullPath
})
})
})
},
closeSelectedTag
(
view
)
{
this
.
$store
.
dispatch
(
'tagsView/delView'
,
view
).
then
(({
visitedViews
})
=>
{
if
(
this
.
isActive
(
view
))
{
this
.
toLastView
(
visitedViews
,
view
)
}
})
},
closeOthersTags
()
{
this
.
$router
.
push
(
this
.
selectedTag
)
this
.
$store
.
dispatch
(
'tagsView/delOthersViews'
,
this
.
selectedTag
).
then
(()
=>
{
this
.
moveToCurrentTag
()
})
},
closeAllTags
(
view
)
{
this
.
$store
.
dispatch
(
'tagsView/delAllViews'
).
then
(({
visitedViews
})
=>
{
if
(
this
.
affixTags
.
some
(
tag
=>
tag
.
path
===
view
.
path
))
{
return
}
this
.
toLastView
(
visitedViews
,
view
)
})
},
toLastView
(
visitedViews
,
view
)
{
const
latestView
=
visitedViews
.
slice
(
-
1
)[
0
]
if
(
latestView
)
{
this
.
$router
.
push
(
latestView
.
fullPath
)
}
else
{
// now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs.
if
(
view
.
name
===
'Dashboard'
)
{
// to reload home page
this
.
$router
.
replace
({
path
:
'/redirect'
+
view
.
fullPath
})
}
else
{
this
.
$router
.
push
(
'/'
)
}
}
},
openMenu
(
tag
,
e
)
{
const
menuMinWidth
=
105
const
offsetLeft
=
this
.
$el
.
getBoundingClientRect
().
left
// container margin left
const
offsetWidth
=
this
.
$el
.
offsetWidth
// container width
const
maxLeft
=
offsetWidth
-
menuMinWidth
// left boundary
const
left
=
e
.
clientX
-
offsetLeft
+
15
// 15: margin right
<!--export default {-->
<!-- name: 'TagsView',-->
<!-- components: { ScrollPane },-->
<!-- data() {-->
<!-- return {-->
<!-- visible: false,-->
<!-- top: 0,-->
<!-- left: 0,-->
<!-- selectedTag: {},-->
<!-- affixTags: []-->
<!-- }-->
<!-- },-->
<!-- computed: {-->
<!-- visitedViews() {-->
<!-- return this.$store.state.tagsView.visitedViews-->
<!-- },-->
<!-- routes() {-->
<!-- return this.$store.state.permission.routes-->
<!-- },-->
<!-- theme() {-->
<!-- return this.$store.state.settings.theme-->
<!-- }-->
<!-- },-->
<!-- watch: {-->
<!-- $route() {-->
<!-- this.addTags()-->
<!-- this.moveToCurrentTag()-->
<!-- },-->
<!-- visible(value) {-->
<!-- if (value) {-->
<!-- document.body.addEventListener('click', this.closeMenu)-->
<!-- } else {-->
<!-- document.body.removeEventListener('click', this.closeMenu)-->
<!-- }-->
<!-- }-->
<!-- },-->
<!-- mounted() {-->
<!-- this.initTags()-->
<!-- this.addTags()-->
<!-- },-->
<!-- methods: {-->
<!-- isActive(route) {-->
<!-- return route.path === this.$route.path-->
<!-- },-->
<!-- activeStyle(tag) {-->
<!-- if (!this.isActive(tag)) return {}-->
<!-- return {-->
<!-- 'background-color': this.theme,-->
<!-- 'border-color': this.theme-->
<!-- }-->
<!-- },-->
<!-- isAffix(tag) {-->
<!-- return tag.meta && tag.meta.affix-->
<!-- },-->
<!-- filterAffixTags(routes, basePath = '/') {-->
<!-- let tags = []-->
<!-- routes.forEach(route => {-->
<!-- if (route.meta && route.meta.affix) {-->
<!-- const tagPath = path.resolve(basePath, route.path)-->
<!-- tags.push({-->
<!-- fullPath: tagPath,-->
<!-- path: tagPath,-->
<!-- name: route.name,-->
<!-- meta: { ...route.meta }-->
<!-- })-->
<!-- }-->
<!-- if (route.children) {-->
<!-- const tempTags = this.filterAffixTags(route.children, route.path)-->
<!-- if (tempTags.length >= 1) {-->
<!-- tags = [...tags, ...tempTags]-->
<!-- }-->
<!-- }-->
<!-- })-->
<!-- return tags-->
<!-- },-->
<!-- initTags() {-->
<!-- const affixTags = this.affixTags = this.filterAffixTags(this.routes)-->
<!-- for (const tag of affixTags) {-->
<!-- // Must have tag name-->
<!-- if (tag.name) {-->
<!-- this.$store.dispatch('tagsView/addVisitedView', tag)-->
<!-- }-->
<!-- }-->
<!-- },-->
<!-- addTags() {-->
<!-- const { name } = this.$route-->
<!-- if (name) {-->
<!-- this.$store.dispatch('tagsView/addView', this.$route)-->
<!-- }-->
<!-- if (this.visitedViews.length > 10) {-->
<!-- this.closeSelectedTag(this.visitedViews[0])-->
<!-- }-->
<!-- return false-->
<!-- },-->
<!-- moveToCurrentTag() {-->
<!-- const tags = this.$refs.tag-->
<!-- this.$nextTick(() => {-->
<!-- for (const tag of tags) {-->
<!-- if (tag.to.path === this.$route.path) {-->
<!-- this.$refs.scrollPane.moveToTarget(tag)-->
<!-- // when query is different then update-->
<!-- if (tag.to.fullPath !== this.$route.fullPath) {-->
<!-- this.$store.dispatch('tagsView/updateVisitedView', this.$route)-->
<!-- }-->
<!-- break-->
<!-- }-->
<!-- }-->
<!-- })-->
<!-- },-->
<!-- refreshSelectedTag(view) {-->
<!-- this.$store.dispatch('tagsView/delCachedView', view).then(() => {-->
<!-- const { fullPath } = view-->
<!-- this.$nextTick(() => {-->
<!-- this.$router.replace({-->
<!-- path: '/redirect' + fullPath-->
<!-- })-->
<!-- })-->
<!-- })-->
<!-- },-->
<!-- closeSelectedTag(view) {-->
<!-- this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {-->
<!-- if (this.isActive(view)) {-->
<!-- this.toLastView(visitedViews, view)-->
<!-- }-->
<!-- })-->
<!-- },-->
<!-- closeOthersTags() {-->
<!-- this.$router.push(this.selectedTag)-->
<!-- this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {-->
<!-- this.moveToCurrentTag()-->
<!-- })-->
<!-- },-->
<!-- closeAllTags(view) {-->
<!-- this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {-->
<!-- if (this.affixTags.some(tag => tag.path === view.path)) {-->
<!-- return-->
<!-- }-->
<!-- this.toLastView(visitedViews, view)-->
<!-- })-->
<!-- },-->
<!-- toLastView(visitedViews, view) {-->
<!-- const latestView = visitedViews.slice(-1)[0]-->
<!-- if (latestView) {-->
<!-- this.$router.push(latestView.fullPath)-->
<!-- } else {-->
<!-- // now the default is to redirect to the home page if there is no tags-view,-->
<!-- // you can adjust it according to your needs.-->
<!-- if (view.name === 'Dashboard') {-->
<!-- // to reload home page-->
<!-- this.$router.replace({ path: '/redirect' + view.fullPath })-->
<!-- } else {-->
<!-- this.$router.push('/')-->
<!-- }-->
<!-- }-->
<!-- },-->
<!-- openMenu(tag, e) {-->
<!-- const menuMinWidth = 105-->
<!-- const offsetLeft = this.$el.getBoundingClientRect().left // container margin left-->
<!-- const offsetWidth = this.$el.offsetWidth // container width-->
<!-- const maxLeft = offsetWidth - menuMinWidth // left boundary-->
<!-- const left = e.clientX - offsetLeft + 15 // 15: margin right-->
if
(
left
>
maxLeft
)
{
this
.
left
=
maxLeft
}
else
{
this
.
left
=
left
}
<!-- if (left > maxLeft) {-->
<!-- this.left = maxLeft-->
<!-- } else {-->
<!-- this.left = left-->
<!-- }-->
this
.
top
=
e
.
clientY
-
35
this
.
visible
=
true
this
.
selectedTag
=
tag
},
closeMenu
()
{
this
.
visible
=
false
},
handleScroll
()
{
this
.
closeMenu
()
}
}
}
<
/
script
>
<!-- this.top = e.clientY - 35-->
<!-- this.visible = true-->
<!-- this.selectedTag = tag-->
<!-- },-->
<!-- closeMenu() {-->
<!-- this.visible = false-->
<!-- },-->
<!-- handleScroll() {-->
<!-- this.closeMenu()-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</script>--
>
<
style
lang=
"scss"
scoped
>
.tags-view-container
{
height
:
31px
;
width
:
100%
;
background
:
#F4F4F4
;
//border-bottom: 1px solid #d8dce5;
//box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
margin
:
0
14px
;
.tags-view-wrapper
{
.tags-view-item
{
display
:
inline-block
;
position
:
relative
;
cursor
:
pointer
;
height
:
27px
;
line-height
:
26px
;
//border: 1px solid #d8dce5;
color
:
#495060
;
background
:
#fff
;
padding
:
0
10px
;
font-size
:
14px
;
margin-left
:
5px
;
margin-top
:
4px
;
&
:first-of-type
{
margin-left
:
0
;
}
&
:last-of-type
{
margin-right
:
15px
;
}
&
.active
{
background-color
:
#fff
;
color
:
$color-theme
;
border-color
:
transparent
;
//&::before {
// content: '';
// background: #fff;
// display: inline-block;
// width: 8px;
// height: 8px;
// border-radius: 50%;
// position: relative;
// margin-right: 2px;
//}
}
}
}
.contextmenu
{
margin
:
0
;
background
:
#fff
;
z-index
:
3000
;
position
:
absolute
;
list-style-type
:
none
;
padding
:
5px
0
;
border-radius
:
4px
;
font-size
:
12px
;
font-weight
:
400
;
color
:
#333
;
box-shadow
:
2px
2px
3px
0
rgba
(
0
,
0
,
0
,
.3
);
li
{
margin
:
0
;
padding
:
7px
16px
;
cursor
:
pointer
;
&
:hover
{
background
:
#eee
;
}
}
}
}
<
/
style
>
<
!--<style lang="scss" scoped>--
>
<!--.tags-view-container {-->
<!-- height: 31px;-->
<!-- width: 100%;-->
<!-- background: #F4F4F4;-->
<!-- //border-bottom: 1px solid #d8dce5;-->
<!-- //box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);-->
<!-- margin: 0 14px;-->
<!-- .tags-view-wrapper {-->
<!-- .tags-view-item {-->
<!-- display: inline-block;-->
<!-- position: relative;-->
<!-- cursor: pointer;-->
<!-- height: 27px;-->
<!-- line-height: 26px;-->
<!-- //border: 1px solid #d8dce5;-->
<!-- color: #495060;-->
<!-- background: #fff;-->
<!-- padding: 0 10px;-->
<!-- font-size: 14px;-->
<!-- margin-left: 5px;-->
<!-- margin-top: 4px;-->
<!-- &:first-of-type {-->
<!-- margin-left: 0;-->
<!-- }-->
<!-- &:last-of-type {-->
<!-- margin-right: 15px;-->
<!-- }-->
<!-- &.active {-->
<!-- background-color: #fff;-->
<!-- color: $color-theme;-->
<!-- border-color: transparent;-->
<!-- //&::before {-->
<!-- // content: '';-->
<!-- // background: #fff;-->
<!-- // display: inline-block;-->
<!-- // width: 8px;-->
<!-- // height: 8px;-->
<!-- // border-radius: 50%;-->
<!-- // position: relative;-->
<!-- // margin-right: 2px;-->
<!-- //}-->
<!-- }-->
<!-- }-->
<!-- }-->
<!-- .contextmenu {-->
<!-- margin: 0;-->
<!-- background: #fff;-->
<!-- z-index: 3000;-->
<!-- position: absolute;-->
<!-- list-style-type: none;-->
<!-- padding: 5px 0;-->
<!-- border-radius: 4px;-->
<!-- font-size: 12px;-->
<!-- font-weight: 400;-->
<!-- color: #333;-->
<!-- box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);-->
<!-- li {-->
<!-- margin: 0;-->
<!-- padding: 7px 16px;-->
<!-- cursor: pointer;-->
<!-- &:hover {-->
<!-- background: #eee;-->
<!-- }-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</style>--
>
<
style
lang=
"scss"
>
//reset element css of el-icon-close
.tags-view-wrapper
{
.tags-view-item
{
.el-icon-close
{
width
:
16px
;
height
:
16px
;
vertical-align
:
2px
;
border-radius
:
50%
;
text-align
:
center
;
transition
:
all
.3s
cubic-bezier
(
.645
,
.045
,
.355
,
1
);
transform-origin
:
100%
50%
;
&
:before
{
transform
:
scale
(
.6
);
display
:
inline-block
;
vertical-align
:
-3px
;
}
&
:hover
{
background-color
:
#b4bccc
;
color
:
#fff
;
}
}
}
}
<
/
style
>
<
!--<style lang="scss">--
>
<!--//reset element css of el-icon-close-->
<!--.tags-view-wrapper {-->
<!-- .tags-view-item {-->
<!-- .el-icon-close {-->
<!-- width: 16px;-->
<!-- height: 16px;-->
<!-- vertical-align: 2px;-->
<!-- border-radius: 50%;-->
<!-- text-align: center;-->
<!-- transition: all .3s cubic-bezier(.645, .045, .355, 1);-->
<!-- transform-origin: 100% 50%;-->
<!-- &:before {-->
<!-- transform: scale(.6);-->
<!-- display: inline-block;-->
<!-- vertical-align: -3px;-->
<!-- }-->
<!-- &:hover {-->
<!-- background-color: #b4bccc;-->
<!-- color: #fff;-->
<!-- }-->
<!-- }-->
<!-- }-->
<!--}-->
<
!--</style>--
>
src/layout/components/header.vue
View file @
b7cbfd82
<
template
>
<div
class=
"navbar"
>
<div
class=
"title-box"
>
<hamburger
:is-active=
"sidebar.opened"
class=
"hamburger-container"
@
toggleClick=
"toggleSideBar"
/
>
<el-dropdown
class=
"change-sys"
@
command=
"handleCommand"
>
<!--
<span
class=
"el-dropdown-link"
>
-->
<!--
业务中台
<i
class=
"el-icon-arrow-down el-icon--right"
/>
-->
<!--
</span>
-->
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
v-for=
"(item) in appList"
:key=
"item.businessId"
:command=
"specialTag !== '1' ? item.pcUrl : ''"
>
{{
item
.
system
}}
</el-dropdown-item
>
</el-dropdown-menu
>
</el-dropdown
>
<!--
<hamburger-->
<!-- :is-active="sidebar.opened"-->
<!-- class="hamburger-container"-->
<!-- @toggleClick="toggleSideBar"-->
<!-- />--
>
<!--
<el-dropdown-->
<!-- class="change-sys"-->
<!-- @command="handleCommand"-->
<!-- >--
>
<!--
<!–
<span
class=
"el-dropdown-link"
>
–>
-->
<!--
<!– 业务中台
<i
class=
"el-icon-arrow-down el-icon--right"
/>
–>
-->
<!--
<!–
</span>
–>
-->
<!--
<el-dropdown-menu-->
<!-- slot="dropdown"-->
<!-- >--
>
<!--
<el-dropdown-item-->
<!-- v-for="(item) in appList"-->
<!-- :key="item.businessId"-->
<!-- :command="specialTag !== '1' ? item.pcUrl : ''"-->
<!-- >--
>
<!--
{{
item
.
system
}}
-->
<!--
</el-dropdown-item>
--
>
<!--
</el-dropdown-menu>
--
>
<!--
</el-dropdown>
--
>
</div>
<div
class=
"right-menu"
>
<!--
<i
class=
"el-icon-info"
/>
-->
...
...
@@ -81,7 +81,7 @@ export default {
])
},
mounted
()
{
this
.
getInAdhibitions
()
//
this.getInAdhibitions()
},
methods
:
{
handleCommand
(
param
)
{
...
...
@@ -89,11 +89,11 @@ export default {
window
.
location
.
href
=
param
}
},
getInAdhibitions
()
{
queryInAdhibitions
({
businessId
:
'zt'
}).
then
(
res
=>
{
this
.
appList
.
splice
(
0
,
0
,
...
res
.
data
)
})
},
//
getInAdhibitions() {
//
queryInAdhibitions({ businessId: 'zt' }).then(res => {
//
this.appList.splice(0, 0, ...res.data)
//
})
//
},
toggleSideBar
()
{
this
.
$store
.
dispatch
(
'app/toggleSideBar'
)
},
...
...
src/layout/index.vue
View file @
b7cbfd82
...
...
@@ -102,7 +102,7 @@ export default {
//top: 0;
//right: 0;
//z-index: 9;
width
:
calc
(
100%
-
#{
$sideBarWidth
}
);
//
width: calc(100% - #{$sideBarWidth});
transition
:
width
0
.28s
;
}
...
...
src/styles/sidebar.scss
View file @
b7cbfd82
...
...
@@ -4,7 +4,7 @@
padding-top
:
6
.4vh
;
min-height
:
100%
;
transition
:
margin-left
0
.28s
;
margin-left
:
$sideBarWidth
;
//
margin-left: $sideBarWidth;
position
:
relative
;
}
...
...
src/views/home/index.vue
0 → 100644
View file @
b7cbfd82
<
template
>
<div>
aaaaaaaaaaaa
</div>
</
template
>
<
script
>
export
default
{
name
:
'Index'
}
</
script
>
<
style
scoped
>
</
style
>
src/views/overView/dashboard/equipment.vue
deleted
100644 → 0
View file @
c57de5f5
<
template
>
<div
class=
"equipment"
>
<el-row
:gutter=
"12"
>
<el-col
:span=
"6"
>
<div
class=
"equipmentLeft"
>
<el-card
class=
"box-card"
>
<div
style=
"display: flex;margin-top: 10px"
>
<el-divider
direction=
"vertical"
/>
<div
class=
"cardTitle"
>
全网信息统计
</div>
</div>
<el-row
style=
"margin-top: 20px"
>
<el-col
:span=
"8"
>
<div
class=
"cardChild"
>
<img
:src=
"equipmentIcon"
class=
"sidebar-logo"
>
<div
class=
"cardFont"
>
设备总数
</div>
<div
class=
"cardNum"
>
104
</div>
</div>
</el-col>
<el-col
:span=
"8"
>
<div
class=
"cardChild"
>
<img
:src=
"monitorIcon"
class=
"sidebar-logo"
>
<div
class=
"cardFont"
>
监控总数
</div>
<div
class=
"cardNum"
>
2143
</div>
</div>
</el-col>
<el-col
:span=
"8"
>
<div
class=
"cardChild"
>
<img
:src=
"warnIcon"
class=
"sidebar-logo"
>
<div
class=
"cardFont"
>
警告数
</div>
<div
class=
"cardNum"
>
22
</div>
</div>
</el-col>
</el-row>
</el-card>
<el-card
class=
"box-card"
>
<div
style=
"display: flex;margin-top: 10px"
>
<el-divider
direction=
"vertical"
/>
<div
class=
"cardTitle"
>
故障统计TOP5
</div>
</div>
<el-row
style=
"margin-top: 20px"
>
<div
id=
"echarts-enter"
class=
"span_1"
>
<div
id=
"dataCharts_enter"
ref=
"chart_enter"
style=
"height: 25vh"
/>
</div>
</el-row>
</el-card>
<el-card
class=
"box-card"
>
<div
style=
"display: flex;margin-top: 10px;margin-bottom: 10px"
>
<el-divider
direction=
"vertical"
/>
<div
class=
"cardTitle"
>
未处理警告
</div>
</div>
<div
v-for=
"(item, index) in messageList"
:key=
"index"
class=
"warnMessage"
>
<div>
<span>
{{
item
.
label
}}
</span>
<span>
{{
item
.
time
}}
</span>
</div>
</div>
</el-card>
</div>
</el-col>
<el-col
:span=
"12"
>
<div
class=
"equipmentMiddle"
>
<div
class=
"bigTitle"
>
IT一体化监控平台
</div>
<div
class=
"middleBody"
>
<div
class=
"middleChild"
>
<div
id=
"echarts-proLineMonitor"
class=
"span_1"
>
<el-row>
<el-col
:span=
"16"
>
<div
id=
"dataCharts_proLineMonitor"
ref=
"chart_stay"
style=
"height: 30vh"
/>
</el-col>
<el-col
:span=
"8"
>
<div
class=
"middleLattice"
>
<div
style=
"margin-bottom: 15px;margin-top: 15px"
>
设备总数:104
</div>
<div
class=
"middleLatticeChild"
>
正常:78
</div>
<div
class=
"middleLatticeChild"
>
故障:9
</div>
<div
class=
"middleLatticeChild"
>
危险:3
</div>
<div
class=
"middleLatticeChild"
>
未知:14
</div>
<div
class=
"middleLatticeChild"
style=
"border-bottom: 1px solid black"
>
禁止:0
</div>
</div>
</el-col>
</el-row>
</div>
</div>
<div
class=
"middleChild"
>
<div
id=
"echarts-MonitoringPpoint"
class=
"span_1"
>
<el-row>
<el-col
:span=
"16"
>
<div
id=
"dataCharts_MonitoringPpoint"
ref=
"chart_stay"
style=
"height: 30vh"
/>
</el-col>
<el-col
:span=
"8"
>
<div
class=
"middleLattice"
>
<div
style=
"margin-bottom: 15px;margin-top: 15px"
>
监测点总数:2143
</div>
<div
class=
"middleLatticeChild"
>
正常:1658
</div>
<div
class=
"middleLatticeChild"
>
故障:17
</div>
<div
class=
"middleLatticeChild"
>
危险:12
</div>
<div
class=
"middleLatticeChild"
>
未知:455
</div>
<div
class=
"middleLatticeChild"
style=
"border-bottom: 1px solid black"
>
禁止:1
</div>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
</div>
</el-col>
<el-col
:span=
"6"
>
<div
class=
"equipmentRight"
>
<el-card
class=
"box-card"
>
<div
style=
"display: flex;margin-top: 10px"
>
<el-divider
direction=
"vertical"
/>
<div
class=
"cardTitle"
>
全网信息统计
</div>
</div>
<el-row
style=
"margin-top: 20px"
>
<el-col
:span=
"8"
>
<div
class=
"cardChild"
>
<img
:src=
"equipmentIcon"
class=
"sidebar-logo"
>
<div
class=
"cardFont"
>
设备总数
</div>
<div
class=
"cardNum"
>
104
</div>
</div>
</el-col>
<el-col
:span=
"8"
>
<div
class=
"cardChild"
>
<img
:src=
"monitorIcon"
class=
"sidebar-logo"
>
<div
class=
"cardFont"
>
监控总数
</div>
<div
class=
"cardNum"
>
2143
</div>
</div>
</el-col>
<el-col
:span=
"8"
>
<div
class=
"cardChild"
>
<img
:src=
"warnIcon"
class=
"sidebar-logo"
>
<div
class=
"cardFont"
>
警告数
</div>
<div
class=
"cardNum"
>
22
</div>
</div>
</el-col>
</el-row>
</el-card>
<el-card
class=
"box-card"
>
<div
style=
"display: flex;margin-top: 10px"
>
<el-divider
direction=
"vertical"
/>
<div
class=
"cardTitle"
>
故障统计TOP5
</div>
</div>
<el-row
style=
"margin-top: 20px"
>
<div
id=
"echarts-enters"
class=
"span_1"
>
<div
id=
"dataCharts_enters"
ref=
"chart_enter"
style=
"height: 25vh"
/>
</div>
</el-row>
</el-card>
<el-card
class=
"box-card"
>
<div
style=
"display: flex;margin-top: 10px;margin-bottom: 10px"
>
<el-divider
direction=
"vertical"
/>
<div
class=
"cardTitle"
>
未处理警告
</div>
</div>
<div
v-for=
"(item, index) in messageList"
:key=
"index"
class=
"warnMessage"
>
<div>
<span>
{{
item
.
label
}}
</span>
<span>
{{
item
.
time
}}
</span>
</div>
</div>
</el-card>
</div>
</el-col>
</el-row>
</div>
</
template
>
<
script
>
import
*
as
echarts
from
'echarts'
export
default
{
name
:
'Equipment'
,
data
()
{
return
{
messageList
:
[
{
label
:
'智盘服务器-10.1.154'
,
time
:
'2019-12-09'
},
{
label
:
'智盘服务器-10.1.154'
,
time
:
'2019-12-09'
},
{
label
:
'智盘服务器-10.1.154'
,
time
:
'2019-12-09'
},
{
label
:
'智盘服务器-10.1.154'
,
time
:
'2019-12-09'
}
],
equipmentIcon
:
require
(
'@/assets/image/logo.png'
),
monitorIcon
:
require
(
'@/assets/image/logo.png'
),
warnIcon
:
require
(
'@/assets/image/logo.png'
)
}
},
mounted
()
{
this
.
genderStatistics
()
this
.
getProLineMonitor
()
this
.
getMonitorPoint
()
// 通过监听内容部分的宽度让图表resize
var
elementResizeDetectorMaker
=
require
(
'element-resize-detector'
)
var
erd
=
elementResizeDetectorMaker
()
var
that
=
this
erd
.
listenTo
(
document
.
getElementById
(
'echarts-enter'
),
function
(
element
)
{
var
width
=
element
.
offsetWidth
var
height
=
element
.
offsetHeight
self
.
tableHeight
=
height
// 将监听到的宽高进行赋值
self
.
tableWidth
=
width
that
.
$nextTick
(
function
()
{
console
.
log
(
'Size: '
+
width
+
'x'
+
height
)
// 使echarts尺寸重置
echarts
.
init
(
document
.
getElementById
(
'dataCharts_enter'
)).
resize
()
})
})
erd
.
listenTo
(
document
.
getElementById
(
'echarts-proLineMonitor'
),
function
(
element
)
{
var
width
=
element
.
offsetWidth
var
height
=
element
.
offsetHeight
self
.
tableHeight
=
height
// 将监听到的宽高进行赋值
self
.
tableWidth
=
width
that
.
$nextTick
(
function
()
{
console
.
log
(
'Size: '
+
width
+
'x'
+
height
)
// 使echarts尺寸重置
echarts
.
init
(
document
.
getElementById
(
'dataCharts_proLineMonitor'
)).
resize
()
})
})
erd
.
listenTo
(
document
.
getElementById
(
'echarts-MonitoringPpoint'
),
function
(
element
)
{
var
width
=
element
.
offsetWidth
var
height
=
element
.
offsetHeight
self
.
tableHeight
=
height
// 将监听到的宽高进行赋值
self
.
tableWidth
=
width
that
.
$nextTick
(
function
()
{
console
.
log
(
'Size: '
+
width
+
'x'
+
height
)
// 使echarts尺寸重置
echarts
.
init
(
document
.
getElementById
(
'dataCharts_MonitoringPpoint'
)).
resize
()
})
})
},
methods
:
{
/** 故障统计TOP5
* */
genderStatistics
()
{
const
myChartGender
=
echarts
.
init
(
document
.
getElementById
(
'dataCharts_enter'
))
var
optionEnter
=
{
tooltip
:
{
trigger
:
'axis'
,
axisPointer
:
{
type
:
'shadow'
}
},
legend
:
{},
grid
:
{
top
:
'2%'
,
left
:
'5%'
,
right
:
'4%'
,
containLabel
:
true
},
xAxis
:
{
type
:
'value'
},
yAxis
:
{
type
:
'category'
,
data
:
[
'其他'
,
'物联网'
,
'应用和业务'
,
'服务器'
,
'网络设备'
]
},
series
:
[
{
type
:
'bar'
,
data
:
[
0
,
0
,
1
,
1
,
7
]
}
]
}
myChartGender
.
setOption
(
optionEnter
)
},
/** 设备*/
getProLineMonitor
()
{
const
myChartAge
=
echarts
.
init
(
document
.
getElementById
(
'dataCharts_proLineMonitor'
))
var
optionArea
=
{
tooltip
:
{
trigger
:
'item'
},
grid
:
{
top
:
'2%'
,
left
:
'5%'
,
right
:
'4%'
,
containLabel
:
true
},
title
:
{
text
:
'设备'
,
left
:
'center'
,
top
:
'50%'
,
textStyle
:
{
textAlign
:
'center'
,
fill
:
'#333'
,
fontSize
:
18
,
fontWeight
:
400
}
},
graphic
:
{
type
:
'text'
,
left
:
'center'
,
top
:
'40%'
,
style
:
{
text
:
'104'
,
textAlign
:
'center'
,
fill
:
'#333'
,
fontSize
:
20
}
},
series
:
[
{
name
:
'Access From'
,
type
:
'pie'
,
radius
:
[
'30%'
,
'70%'
],
avoidLabelOverlap
:
false
,
itemStyle
:
{
borderRadius
:
10
,
borderColor
:
'#fff'
,
borderWidth
:
2
},
emphasis
:
{
itemStyle
:
{
shadowBlur
:
10
,
shadowOffsetX
:
0
,
shadowColor
:
'rgba(0, 0, 0, 0.5)'
}
},
data
:
[
{
value
:
78
,
name
:
'正常 78个'
},
{
value
:
9
,
name
:
'故障 9个'
},
{
value
:
3
,
name
:
'危险 3个'
},
{
value
:
14
,
name
:
'未知 14个'
},
{
value
:
0
,
name
:
'禁止 0个'
}
]
}
]
}
myChartAge
.
setOption
(
optionArea
)
},
/** 监测点*/
getMonitorPoint
()
{
const
myChartAge
=
echarts
.
init
(
document
.
getElementById
(
'dataCharts_MonitoringPpoint'
))
var
optionArea
=
{
tooltip
:
{
trigger
:
'item'
},
grid
:
{
top
:
'2%'
,
left
:
'5%'
,
right
:
'4%'
,
containLabel
:
true
},
title
:
{
text
:
'监测点'
,
left
:
'center'
,
top
:
'50%'
,
textStyle
:
{
textAlign
:
'center'
,
fill
:
'#333'
,
fontSize
:
18
,
fontWeight
:
400
}
},
graphic
:
{
type
:
'text'
,
left
:
'center'
,
top
:
'40%'
,
style
:
{
text
:
'2143'
,
textAlign
:
'center'
,
fill
:
'#333'
,
fontSize
:
20
}
},
series
:
[
{
name
:
'Access From'
,
type
:
'pie'
,
radius
:
[
'30%'
,
'70%'
],
avoidLabelOverlap
:
false
,
itemStyle
:
{
borderRadius
:
10
,
borderColor
:
'#fff'
,
borderWidth
:
2
},
emphasis
:
{
itemStyle
:
{
shadowBlur
:
10
,
shadowOffsetX
:
0
,
shadowColor
:
'rgba(0, 0, 0, 0.5)'
}
},
data
:
[
{
value
:
1658
,
name
:
'正常 1658个'
},
{
value
:
17
,
name
:
'故障 17个'
},
{
value
:
12
,
name
:
'危险 12个'
},
{
value
:
455
,
name
:
'未知 455个'
},
{
value
:
1
,
name
:
'禁止 1个'
}
]
}
]
}
myChartAge
.
setOption
(
optionArea
)
}
}
}
</
script
>
<
style
lang=
"scss"
>
.equipment
{
padding
:
15px
;
.equipmentMiddle
{
.middleLattice
{
.middleLatticeChild
{
width
:
90px
;
padding
:
5px
;
border
:
1px
solid
black
;
border-bottom
:
0
;
}
}
.middleBody
{
.middleChild
{
margin-bottom
:
30px
;
}
}
.bigTitle
{
text-align
:
center
;
font-size
:
35px
;
color
:
#46bcf2
;
}
}
.box-card
{
height
:
25vh
;
margin-bottom
:
10px
;
.el-divider--vertical
{
width
:
5px
!
important
;
background-color
:
#46bcf2
!
important
;
}
.warnMessage
{
padding-bottom
:
5px
;
margin-bottom
:
5px
;
border-bottom
:
1px
solid
#46bcf2
;
}
.cardTitle
{
text-align
:
left
;
font-weight
:
bold
;
}
.cardChild
{
.sidebar-logo
{
width
:
55px
;
}
.cardFont
{
margin-top
:
5px
;
}
.cardNum
{
margin-top
:
10px
;
font-size
:
20px
;
}
}
.el-card__body
{
text-align
:
center
!
important
;
padding
:
10px
!
important
;
}
.span_middle
{
font-size
:
14px
;
}
.topChild
{
width
:
160px
;
padding
:
15px
;
display
:inline-flex
;
.cardLabel
{
padding-left
:
10px
;
text-align
:
center
;
}
}
}
}
</
style
>
src/views/test/test.vue
deleted
100644 → 0
View file @
c57de5f5
<
template
>
<div>
<el-select
v-model=
"value"
placeholder=
"请选择"
>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<el-table
:data=
"tableData"
border
style=
"width: 100%"
>
<el-table-column
label=
"序号"
type=
"index"
width=
"50"
>
</el-table-column>
<el-table-column
prop=
"date"
label=
"日期"
width=
"180"
/>
<el-table-column
prop=
"name"
label=
"姓名"
width=
"180"
/>
<el-table-column
prop=
"address"
label=
"地址"
/>
</el-table>
<el-pagination
background
layout=
"prev, pager, next"
:total=
"1000"
/>
</div>
</
template
>
<
script
>
export
default
{
data
()
{
return
{
options
:
[{
value
:
'选项1'
,
label
:
'黄金糕'
},
{
value
:
'选项2'
,
label
:
'双皮奶'
},
{
value
:
'选项3'
,
label
:
'蚵仔煎'
},
{
value
:
'选项4'
,
label
:
'龙须面'
},
{
value
:
'选项5'
,
label
:
'北京烤鸭'
}],
value
:
''
,
tableData
:
[{
date
:
'2016-05-02'
,
name
:
'王小虎'
,
address
:
'上海市普陀区金沙江路 1518 弄'
},
{
date
:
'2016-05-04'
,
name
:
'王小虎'
,
address
:
'上海市普陀区金沙江路 1517 弄'
},
{
date
:
'2016-05-01'
,
name
:
'王小虎'
,
address
:
'上海市普陀区金沙江路 1519 弄'
},
{
date
:
'2016-05-03'
,
name
:
'王小虎'
,
address
:
'上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</
script
>
vue.config.js
View file @
b7cbfd82
...
...
@@ -43,7 +43,7 @@ module.exports = {
lintOnSave
:
process
.
env
.
NODE_ENV
===
'development'
,
productionSourceMap
:
false
,
devServer
:
{
// port: port
,
port
:
8083
,
// open: true,
// overlay: {
// warnings: false,
...
...
@@ -81,7 +81,7 @@ module.exports = {
[
process
.
env
.
VUE_APP_BASE_API
]:
{
// target: `http://192.168.1.17:10010/internal`,
// target: `http://10.5.87.231:10010/internal`,
target
:
`http://124.71.16.228:80
85
/`
,
target
:
`http://124.71.16.228:80
96
/`
,
changeOrigin
:
true
,
pathRewrite
:
{
[
'^'
+
process
.
env
.
VUE_APP_BASE_API
]:
''
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment