Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dyingstraw
vue-element-admin
提交
b6d97f18
V
vue-element-admin
项目概览
dyingstraw
/
vue-element-admin
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vue-element-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b6d97f18
编写于
12月 13, 2017
作者:
L
leij1ang
提交者:
花裤衩
12月 13, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat[tags-view]: tags-view add contextmenu (#343)
* add the menu by right-clicking the tags * bug fixed * refine
上级
a68413cb
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
200 addition
and
109 deletion
+200
-109
src/store/modules/tagsView.js
src/store/modules/tagsView.js
+31
-0
src/views/layout/components/TagsView.vue
src/views/layout/components/TagsView.vue
+169
-109
未找到文件。
src/store/modules/tagsView.js
浏览文件 @
b6d97f18
...
...
@@ -29,6 +29,25 @@ const tagsView = {
break
}
}
},
DEL_OTHER_VIEWS
:
(
state
,
view
)
=>
{
for
(
const
[
i
,
v
]
of
state
.
visitedViews
.
entries
())
{
if
(
v
.
path
===
view
.
path
)
{
state
.
visitedViews
=
[].
concat
(
state
.
visitedViews
.
slice
(
i
,
i
+
1
))
break
}
}
for
(
const
i
of
state
.
cachedViews
)
{
if
(
i
===
view
.
name
)
{
const
index
=
state
.
cachedViews
.
indexOf
(
i
)
state
.
cachedViews
=
[].
concat
(
state
.
cachedViews
.
slice
(
index
,
i
+
1
))
break
}
}
},
DEL_ALL_VIEWS
:
(
state
)
=>
{
state
.
visitedViews
=
[]
state
.
cachedViews
=
[]
}
},
actions
:
{
...
...
@@ -40,6 +59,18 @@ const tagsView = {
commit
(
'
DEL_VISITED_VIEWS
'
,
view
)
resolve
([...
state
.
visitedViews
])
})
},
delOtherViews
({
commit
,
state
},
view
)
{
return
new
Promise
((
resolve
)
=>
{
commit
(
'
DEL_OTHER_VIEWS
'
,
view
)
resolve
([...
state
.
visitedViews
])
})
},
delAllViews
({
commit
,
state
})
{
return
new
Promise
((
resolve
)
=>
{
commit
(
'
DEL_ALL_VIEWS
'
)
resolve
([...
state
.
visitedViews
])
})
}
}
}
...
...
src/views/layout/components/TagsView.vue
浏览文件 @
b6d97f18
<
template
>
<scroll-pane
class=
'tags-view-container'
ref=
'scrollPane'
>
<router-link
ref=
'tag'
class=
"tags-view-item"
:class=
"isActive(tag)?'active':''"
v-for=
"tag in Array.from(visitedViews)"
:to=
"tag.path"
:key=
"tag.path"
>
{{
generateTitle
(
tag
.
title
)
}}
<span
class=
'el-icon-close'
@
click=
'closeViewTags(tag,$event)'
></span>
</router-link>
</scroll-pane>
<div
class=
"tag-container"
>
<scroll-pane
class=
'tags-view-container'
ref=
'scrollPane'
>
<router-link
ref=
'tag'
class=
"tags-view-item"
:class=
"isActive(tag)?'active':''"
v-for=
"tag in Array.from(visitedViews)"
:to=
"tag.path"
:key=
"tag.path"
@
contextmenu.prevent.native=
"openMenu(tag,$event)"
>
{{
generateTitle
(
tag
.
title
)
}}
<span
class=
'el-icon-close'
@
click=
'closeViewTags(tag,$event)'
></span>
</router-link>
</scroll-pane>
<ul
class=
'contextmenu'
v-show=
"visible"
:style=
"
{left:left+'px',top:top+'px'}">
<li
@
click=
"closeViewTags(selectedTag, $event)"
>
关闭
</li>
<li
@
click=
"closeOtherTags"
>
关闭其他
</li>
<li
@
click=
"closeAllTags"
>
关闭所有
</li>
</ul>
</div>
</
template
>
<
script
>
import
ScrollPane
from
'
@/components/ScrollPane
'
import
{
generateTitle
}
from
'
@/utils/i18n
'
import
ScrollPane
from
'
@/components/ScrollPane
'
import
{
generateTitle
}
from
'
@/utils/i18n
'
export
default
{
components
:
{
ScrollPane
},
computed
:
{
visitedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
visitedViews
}
},
mounted
()
{
this
.
addViewTags
()
},
methods
:
{
generateTitle
,
closeViewTags
(
view
,
$event
)
{
this
.
$store
.
dispatch
(
'
delVisitedViews
'
,
view
).
then
((
views
)
=>
{
if
(
this
.
isActive
(
view
))
{
const
latestView
=
views
.
slice
(
-
1
)[
0
]
if
(
latestView
)
{
this
.
$router
.
push
(
latestView
.
path
)
}
else
{
this
.
$router
.
push
(
'
/
'
)
}
}
})
$event
.
preventDefault
()
},
generateRoute
()
{
if
(
this
.
$route
.
name
)
{
return
this
.
$route
export
default
{
components
:
{
ScrollPane
},
data
()
{
return
{
visible
:
false
,
top
:
0
,
left
:
0
,
selectedTag
:
{}
}
return
false
},
addViewTags
()
{
const
route
=
this
.
generateRoute
()
if
(
!
route
)
{
return
false
computed
:
{
visitedViews
()
{
return
this
.
$store
.
state
.
tagsView
.
visitedViews
}
this
.
$store
.
dispatch
(
'
addVisitedViews
'
,
route
)
},
isActive
(
route
)
{
return
route
.
path
===
this
.
$route
.
path
||
route
.
name
===
this
.
$route
.
name
mounted
(
)
{
this
.
addViewTags
()
},
moveToCurrentTag
()
{
const
tags
=
this
.
$refs
.
tag
this
.
$nextTick
(()
=>
{
for
(
const
tag
of
tags
)
{
if
(
tag
.
to
===
this
.
$route
.
path
)
{
this
.
$refs
.
scrollPane
.
moveToTarget
(
tag
.
$el
)
break
methods
:
{
generateTitle
,
closeViewTags
(
view
,
$event
)
{
this
.
$store
.
dispatch
(
'
delVisitedViews
'
,
view
).
then
((
views
)
=>
{
if
(
this
.
isActive
(
view
))
{
const
latestView
=
views
.
slice
(
-
1
)[
0
]
if
(
latestView
)
{
this
.
$router
.
push
(
latestView
.
path
)
}
else
{
this
.
$router
.
push
(
'
/
'
)
}
}
})
$event
.
preventDefault
()
},
closeOtherTags
()
{
this
.
$router
.
push
(
this
.
selectedTag
.
path
)
this
.
$store
.
dispatch
(
'
delOtherViews
'
,
this
.
selectedTag
)
},
closeAllTags
()
{
this
.
$store
.
dispatch
(
'
delAllViews
'
)
this
.
$router
.
push
(
'
/
'
)
},
generateRoute
()
{
if
(
this
.
$route
.
name
)
{
return
this
.
$route
}
})
}
},
watch
:
{
$route
()
{
this
.
addViewTags
()
this
.
moveToCurrentTag
()
return
false
},
addViewTags
()
{
const
route
=
this
.
generateRoute
()
if
(
!
route
)
{
return
false
}
this
.
$store
.
dispatch
(
'
addVisitedViews
'
,
route
)
},
isActive
(
route
)
{
return
route
.
path
===
this
.
$route
.
path
||
route
.
name
===
this
.
$route
.
name
},
moveToCurrentTag
()
{
const
tags
=
this
.
$refs
.
tag
this
.
$nextTick
(()
=>
{
for
(
const
tag
of
tags
)
{
if
(
tag
.
to
===
this
.
$route
.
path
)
{
this
.
$refs
.
scrollPane
.
moveToTarget
(
tag
.
$el
)
break
}
}
})
},
openMenu
(
tag
,
e
)
{
this
.
visible
=
true
this
.
selectedTag
=
tag
this
.
left
=
e
.
clientX
this
.
top
=
e
.
clientY
},
closeMenu
()
{
this
.
visible
=
false
}
},
watch
:
{
$route
()
{
this
.
addViewTags
()
this
.
moveToCurrentTag
()
},
visible
(
v
)
{
if
(
v
)
{
window
.
addEventListener
(
'
click
'
,
this
.
closeMenu
,
false
)
}
else
{
window
.
removeEventListener
(
'
click
'
,
this
.
closeMenu
,
false
)
}
}
}
}
}
</
script
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
scoped
>
.tags-view
-container
{
background
:
#fff
;
height
:
34px
;
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-item
{
display
:
inline-block
;
position
:
relative
;
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
;
.tag
-container
{
.contextmenu
{
margin
:
0
;
background
:
#fff
;
z-index
:
99999
;
position
:
absolute
;
list-style-type
:
none
;
padding-left
:
0
;
border
:
1px
solid
rgba
(
0
,
0
,
0
,
0
.4
)
;
font-size
:
0
.8rem
;
box-shadow
:
2px
2px
3px
0
rgba
(
0
,
0
,
0
,
.5
)
;
li
{
margin
:
0
;
padding
:
0
.2rem
1
.5rem
0
.3rem
0
.8rem
;
&
:hover
{
background
:
#eee
;
cursor
:
default
;
}
}
}
&
.active
{
background-color
:
#42b983
;
color
:
#fff
;
border-color
:
#42b983
;
&
::before
{
content
:
''
;
background
:
#fff
;
.tags-view-container
{
background
:
#fff
;
height
:
34px
;
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-item
{
display
:
inline-block
;
width
:
8px
;
height
:
8px
;
border-radius
:
50%
;
position
:
relative
;
margin-right
:
2px
;
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
;
}
&
.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
;
}
}
}
}
}
}
</
style
>
<
style
rel=
"stylesheet/scss"
lang=
"scss"
>
.tags-view-container
{
.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-container
{
.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
>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录