Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
finance-manage
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
finance-oa
finance-manage
Commits
30be2a08
Commit
30be2a08
authored
May 26, 2020
by
若依
Committed by
Gitee
May 26, 2020
Browse files
Options
Browse Files
Download
Plain Diff
!22 tagview & sidebar 主题颜色与element ui(全局)同步
Merge pull request !22 from 北风/master
parents
2bd787f6
98bb78a9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
335 additions
and
303 deletions
+335
-303
ruoyi-ui/src/layout/components/Sidebar/index.vue
ruoyi-ui/src/layout/components/Sidebar/index.vue
+49
-46
ruoyi-ui/src/layout/components/TagsView/index.vue
ruoyi-ui/src/layout/components/TagsView/index.vue
+286
-257
No files found.
ruoyi-ui/src/layout/components/Sidebar/index.vue
View file @
30be2a08
<
template
>
<div
:class=
"
{'has-logo':showLogo}">
<logo
v-if=
"showLogo"
: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>
<div
:class=
"
{'has-logo':showLogo}">
<logo
v-if=
"showLogo"
: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=
"settings.theme"
: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
'
@/assets/styles/variables.scss
'
import
{
mapGetters
,
mapState
}
from
"
vuex
"
;
import
Logo
from
"
./Logo
"
;
import
SidebarItem
from
"
./SidebarItem
"
;
import
variables
from
"
@/assets/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
components
:
{
SidebarItem
,
Logo
},
computed
:
{
...
mapState
([
"
settings
"
]),
...
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
>
ruoyi-ui/src/layout/components/TagsView/index.vue
View file @
30be2a08
<
template
>
<div
id=
"tags-view-container"
class=
"tags-view-container"
>
<scroll-pane
ref=
"scrollPane"
class=
"tags-view-wrapper"
>
<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"
@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>
<div
id=
"tags-view-container"
class=
"tags-view-container"
>
<scroll-pane
ref=
"scrollPane"
class=
"tags-view-wrapper"
>
<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
'
import
ScrollPane
from
"
./ScrollPane
"
;
import
path
from
"
path
"
;
export
default
{
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
}
},
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
},
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
components
:
{
ScrollPane
},
data
()
{
return
{
visible
:
false
,
top
:
0
,
left
:
0
,
selectedTag
:
{},
affixTags
:
[]
};
},
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
)
computed
:
{
visitedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
visitedViews
;
},
routes
()
{
return
this
.
$store
.
state
.
permission
.
routes
;
},
theme
()
{
return
this
.
$store
.
state
.
settings
.
theme
;
}
}
},
addTags
()
{
const
{
name
}
=
this
.
$route
if
(
name
)
{
this
.
$store
.
dispatch
(
'
tagsView/addView
'
,
this
.
$route
)
}
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
)
watch
:
{
$route
()
{
this
.
addTags
();
this
.
moveToCurrentTag
();
},
visible
(
value
)
{
if
(
value
)
{
document
.
body
.
addEventListener
(
"
click
"
,
this
.
closeMenu
);
}
else
{
document
.
body
.
removeEventListener
(
"
click
"
,
this
.
closeMenu
);
}
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
)
}
})
mounted
()
{
this
.
initTags
();
this
.
addTags
();
},
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
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
);
}
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
this
.
visible
=
true
this
.
selectedTag
=
tag
},
closeMenu
()
{
this
.
visible
=
false
this
.
top
=
e
.
clientY
;
this
.
visible
=
true
;
this
.
selectedTag
=
tag
;
},
closeMenu
()
{
this
.
visible
=
false
;
}
}
}
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.tags-view-container
{
height
:
34px
;
width
:
100%
;
background
:
#fff
;
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
);
.tags-view-wrapper
{
.tags-view-item
{
display
:
inline-block
;
position
:
relative
;
cursor
:
pointer
;
height
:
26px
;
line-height
:
26px
;
border
:
1px
solid
#d8dce5
;
color
:
#495060
;
background
:
#fff
;
padding
:
0
8px
;
font-size
:
12px
;
margin-left
:
5px
;
margin-top
:
4px
;
&
:first-of-type
{
margin-left
:
15px
;
}
&
:last-of-type
{
margin-right
:
15px
;
}
&
.active
{
background-color
:
#42b983
;
color
:
#fff
;
border-color
:
#42b983
;
&
:
:
before
{
content
:
''
;
background
:
#fff
;
display
:
inline-block
;
width
:
8px
;
height
:
8px
;
border-radius
:
50%
;
position
:
relative
;
margin-right
:
2px
;
height
:
34px
;
width
:
100%
;
background
:
#fff
;
border-bottom
:
1px
solid
#d8dce5
;
box-shadow
:
0
1px
3px
0
rgba
(
0
,
0
,
0
,
0
.12
)
,
0
0
3px
0
rgba
(
0
,
0
,
0
,
0
.04
);
.tags-view-wrapper
{
.tags-view-item
{
display
:
inline-block
;
position
:
relative
;
cursor
:
pointer
;
height
:
26px
;
line-height
:
26px
;
border
:
1px
solid
#d8dce5
;
color
:
#495060
;
background
:
#fff
;
padding
:
0
8px
;
font-size
:
12px
;
margin-left
:
5px
;
margin-top
:
4px
;
&
:first-of-type
{
margin-left
:
15px
;
}
&
:last-of-type
{
margin-right
:
15px
;
}
&
.active
{
background-color
:
#42b983
;
color
:
#fff
;
border-color
:
#42b983
;
&
:
:
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
:
absolut
e
;
list-style-type
:
none
;
padding
:
5px
0
;
border-radius
:
4
px
;
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
;
}
.contextmenu
{
margin
:
0
;
background
:
#fff
;
z-index
:
3000
;
position
:
absolute
;
list-style-type
:
non
e
;
padding
:
5px
0
;
border-radius
:
4px
;
font-size
:
12
px
;
font-weight
:
400
;
color
:
#333
;
box-shadow
:
2px
2px
3px
0
rgba
(
0
,
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
;
}
.tags-view-item
{
.el-icon-close
{
width
:
16px
;
height
:
16px
;
vertical-align
:
2px
;
border-radius
:
50%
;
text-align
:
center
;
transition
:
all
0
.3s
cubic-bezier
(
0
.645
,
0
.045
,
0
.355
,
1
);
transform-origin
:
100%
50%
;
&
:before
{
transform
:
scale
(
0
.6
);
display
:
inline-block
;
vertical-align
:
-3px
;
}
&
:hover
{
background-color
:
#b4bccc
;
color
:
#fff
;
}
}
}
}
}
</
style
>
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