Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Springboot Plus
Commits
5eea9632
Commit
5eea9632
authored
May 11, 2020
by
trumansdo
Browse files
添加自定义树下拉选择器组件
parent
4c9c9cb9
Changes
2
Hide whitespace changes
Inline
Side-by-side
ve-admin/admin-web/src/components/Wrapper/SpTreeSelect.vue
0 → 100644
View file @
5eea9632
// 树形下拉框
<
template
>
<div
class=
"sp-tree-select"
:style=
"
{ width: width }">
<!-- 选中框区 -->
<el-popover
v-model=
"options_show"
placement=
"bottom"
:width=
"width"
:trigger=
"trigger"
:disabled=
"disabled"
transition=
"fade-in"
>
<el-scrollbar
class=
"sp-treeselect-popover"
>
<el-input
v-if=
"filterable"
v-model=
"filterText"
:size=
"size"
placeholder=
"请输入关键词"
></el-input>
<el-tree
ref=
"tree-select"
class=
"sp-options-tree"
highlight-current
:data=
"selfData"
:props=
"selfProps"
:node-key=
"nodeKey"
:show-checkbox=
"checkbox"
:expand-on-click-node=
"false"
:filter-node-method=
"filterNode"
:default-checked-keys=
"checked_keys"
:default-expand-all=
"defaultExpandAll"
:default-expanded-keys=
"defaultExpandedKeys"
@
check=
"handleCheckChange"
@
node-click=
"treeItemClick"
></el-tree>
</el-scrollbar>
<!---->
<div
slot=
"reference"
class=
"selected-box"
:class=
"[
{ 'sp-disabled': disabled, 'no-wrap': nowrap }, sizeClass]"
>
<div
class=
"tag-box"
>
<div
v-show=
"selecteds.length > 0"
>
<template
v-if=
"!collapseTags"
>
<el-tag
v-for=
"item in selecteds"
:key=
"item[nodeKey]"
closable
:size=
"size"
class=
"sp-select-tag"
:title=
"item[selfProps.label]"
@
close=
"tabClose(item[nodeKey])"
>
{{
item
[
selfProps
.
label
]
}}
</el-tag
>
</
template
>
<
template
v-else
>
<el-tag
closable
:size=
"size"
class=
"sp-select-tag"
:title=
"collapseTagsItem[selfProps.label]"
@
close=
"tabClose(collapseTagsItem[nodeKey])"
>
{{
collapseTagsItem
[
selfProps
.
label
]
}}
</el-tag
>
<el-tag
v-if=
"selecteds.length > 1"
:size=
"size"
class=
"sp-select-tag"
>
+
{{
selecteds
.
length
-
1
}}
</el-tag
>
</
template
>
</div>
<p
v-show=
"selecteds.length == 0"
class=
"sp-placeholder-box"
>
{{ placeholder }}
</p>
</div>
<div
class=
"icon-box"
>
<transition
name=
"fade-rotate"
mode=
"out-in"
>
<i
v-if=
"!options_show"
key=
"top"
class=
"el-icon-arrow-down"
></i>
<i
v-else
key=
"btm"
class=
"el-icon-arrow-up"
></i>
</transition>
</div>
</div>
</el-popover>
</div>
</template>
<
script
>
/**
* https://github.com/hql7/wl-vue-select
*/
export
default
{
name
:
'
WlTreeSelect
'
,
model
:
{
prop
:
'
value
'
,
//这里使我们定义的v-model属性
event
:
'
change
'
},
props
:
{
// 数据
data
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 树结构配置
props
:
{
type
:
Object
,
default
:
()
=>
{
return
{};
}
},
// node-key
nodeKey
:
{
type
:
String
,
default
:
'
id
'
},
// 选中数据
value
:
{
type
:
[
String
,
Number
,
Array
,
Object
],
default
:
undefined
},
// 是否可多选
checkbox
:
{
type
:
Boolean
,
default
:
false
},
// 多选时是否将选中值按文字的形式展示
collapseTags
:
{
type
:
Boolean
,
default
:
false
},
// 是否只可选叶子节点
leaf
:
{
type
:
Boolean
,
default
:
false
},
// 宽度
width
:
{
type
:
String
,
default
:
'
auto
'
},
// 触发方式 click/focus/hover/manual
trigger
:
{
type
:
String
,
default
:
'
click
'
},
// 是否禁用
disabled
:
{
type
:
Boolean
,
default
:
false
},
// 是否允许多行显示
nowrap
:
{
type
:
Boolean
,
default
:
false
},
// 多选时,清空选项关闭
noCheckedClose
:
{
type
:
Boolean
,
default
:
false
},
placeholder
:
{
type
:
String
,
default
:
'
请选择
'
},
size
:
{
type
:
String
,
default
:
'
medium
'
},
//是否展开全部
defaultExpandAll
:
{
type
:
Boolean
,
default
:
true
},
//默认展开的节点的 key 的数组
defaultExpandedKeys
:
{
type
:
Array
,
default
:
()
=>
{
return
[];
}
},
// 是否使用搜索
filterable
:
{
type
:
Boolean
,
default
:
false
},
// 自定义筛选函数
filterFnc
:
{
type
:
Function
,
default
:
undefined
}
},
data
()
{
return
{
selecteds
:
[],
// 选中数据
options_show
:
false
,
// 是否显示下拉选项
checked_keys
:
[],
// 默认选中
guid
:
'
00000000-0000-0000-0000-000000000000
'
,
filterText
:
''
};
},
computed
:
{
selfData
()
{
return
this
.
data
;
},
selfProps
()
{
return
{
label
:
'
label
'
,
children
:
'
children
'
,
disabled
:
data
=>
{
return
data
.
disabled
;
},
...
this
.
props
};
},
sizeClass
()
{
let
size_class
=
'
size-medium
'
;
switch
(
this
.
size
)
{
case
'
medium
'
:
size_class
=
'
size-medium
'
;
break
;
case
'
small
'
:
size_class
=
'
size-small
'
;
break
;
case
'
default
'
:
size_class
=
'
size-default
'
;
break
;
case
'
mini
'
:
size_class
=
'
size-mini
'
;
break
;
default
:
size_class
=
'
size-medium
'
;
break
;
}
return
size_class
;
},
// 开启collapseTags时首个选中值
collapseTagsItem
()
{
return
this
.
selecteds
[
0
]
||
{};
}
},
watch
:
{
value
(
val
)
{
this
.
checkDefaultValue
();
},
// 树节点搜索
filterText
(
val
)
{
this
.
$refs
[
'
tree-select
'
].
filter
(
val
);
}
},
created
()
{
this
.
checkDefaultValue
();
},
methods
:
{
// 树节点-checkbox选中
handleCheckChange
(
val
,
{
checkedNodes
,
checkedKeys
})
{
let
nodes
=
this
.
$refs
[
'
tree-select
'
].
getCheckedNodes
(
this
.
leaf
);
this
.
selecteds
=
nodes
;
this
.
$emit
(
'
change
'
,
nodes
);
if
(
checkedKeys
.
length
===
0
&&
this
.
noCheckedClose
)
this
.
options_show
=
false
;
},
// 树节点-点击选中
treeItemClick
(
item
,
node
)
{
if
(
this
.
checkbox
||
(
this
.
leaf
&&
!
node
.
isLeaf
))
{
return
;
}
this
.
selecteds
=
[
item
];
this
.
options_show
=
false
;
this
.
$emit
(
'
change
'
,
this
.
selecteds
);
},
// tag标签关闭
tabClose
(
Id
)
{
if
(
this
.
disabled
)
return
;
if
(
this
.
checkbox
)
{
this
.
$refs
[
'
tree-select
'
].
setChecked
(
Id
,
false
,
true
);
this
.
selecteds
=
this
.
$refs
[
'
tree-select
'
].
getCheckedNodes
();
if
(
this
.
selecteds
.
length
===
0
&&
this
.
noCheckedClose
)
this
.
options_show
=
false
;
}
else
{
this
.
selecteds
=
[];
this
.
$refs
[
'
tree-select
'
].
setCurrentKey
(
null
);
this
.
options_show
=
false
;
}
this
.
$emit
(
'
change
'
,
this
.
selecteds
);
},
// 清空数据
clear
()
{
this
.
selecteds
=
[];
},
// 处理默认选中数据
checkDefaultValue
()
{
let
val
=
this
.
value
;
if
(
!
val
||
(
Array
.
isArray
(
val
)
&&
val
.
length
===
0
))
{
this
.
selecteds
=
[];
if
(
!
this
.
checkbox
)
return
;
this
.
checked_keys
=
[];
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
tree-select
'
].
setCheckedKeys
([]);
});
return
;
}
// 多选处理
if
(
this
.
checkbox
)
{
this
.
checked_keys
=
typeof
val
[
0
]
===
'
object
'
?
val
.
map
(
i
=>
i
[
this
.
nodeKey
])
:
val
;
this
.
$nextTick
(()
=>
{
this
.
selecteds
=
this
.
$refs
[
'
tree-select
'
].
getCheckedNodes
(
this
.
leaf
);
});
return
;
}
// 单选处理
if
(
typeof
val
===
'
object
'
)
{
let
_val
=
Array
.
isArray
(
val
)
?
val
[
0
]
:
val
;
this
.
selecteds
=
[
_val
];
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
tree-select
'
].
setCurrentNode
(
_val
);
});
}
else
{
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
tree-select
'
].
setCurrentKey
(
val
);
let
_node
=
this
.
$refs
[
'
tree-select
'
].
getCurrentNode
();
this
.
selecteds
=
_node
?
[
_node
]
:
[];
});
}
},
// 关闭
closeOptions
()
{
this
.
options_show
=
false
;
},
// 树节点筛选
filterNode
(
value
,
data
)
{
if
(
this
.
filterFnc
)
return
this
.
filterFnc
(
value
,
data
);
if
(
!
value
)
return
true
;
return
data
[
this
.
selfProps
.
label
].
indexOf
(
value
)
!==
-
1
;
}
}
};
</
script
>
<
style
lang=
"scss"
>
.sp-tree-select
{
position
:
relative
;
display
:
inline-block
;
width
:
240px
;
vertical-align
:
middle
;
outline
:
none
;
.selected-box
{
display
:
flex
;
border
:
1px
solid
#dcdfe6
;
padding
:
0
5px
0
8px
;
width
:
100%
;
min-height
:
36px
;
line-height
:
34px
;
box-sizing
:
border-box
;
border-radius
:
4px
;
cursor
:
pointer
;
outline
:
none
;
&
:focus
{
border-color
:
#409eff
;
}
>
.tag-box
{
display
:
inline-block
;
width
:
calc
(
100%
-
20px
);
text-align
:
left
;
}
>
.icon-box
{
float
:
right
;
display
:
flex
;
width
:
20px
;
justify-content
:
center
;
align-items
:
Center
;
color
:
#c0c4cc
;
}
}
.selected-box.size-small
{
min-height
:
32px
;
line-height
:
30px
;
}
.selected-box.size-mini
{
min-height
:
28px
;
line-height
:
26px
;
}
.selected-box.size-default
{
min-height
:
40px
;
line-height
:
38px
;
}
.no-wrap
{
height
:
36px
;
>
.tag-box
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.sp-disabled
{
background
:
#eee
;
cursor
:
no-drop
;
&
:focus
{
border-color
:
#dcdfe6
;
}
.el-tag__close
{
cursor
:
no-drop
;
}
}
.sp-select-tag
{
max-width
:
100%
;
text-overflow
:
ellipsis
;
overflow
:
hidden
;
word-wrap
:
break-word
;
word-break
:
break-all
;
vertical-align
:
middle
;
}
.sp-select-tag
+
.sp-select-tag
{
margin-left
:
4px
;
}
}
.sp-treeselect-popover
{
height
:
360px
;
>
.el-scrollbar__wrap
{
overflow-x
:
hidden
;
}
}
.sp-options-tree
{
display
:
inline-block
!
important
;
min-width
:
100%
;
.el-tree-node__content
{
height
:
34px
;
line-height
:
34px
;
}
}
.sp-placeholder-box
{
color
:
#c0c4cc
;
margin
:
0
;
}
// 过度效果
.fade-in-enter-active
,
.fade-in-leave-active
{
transition
:
all
0
.4s
;
}
.fade-in-enter
,
.fade-in-leave-to
/*
.fade-leave-active
below
version
2
.1.8
*/
{
opacity
:
0
;
transform
:
translateY
(
-10px
);
}
.fade-rotate-enter-active
,
.fade-rotate-leave-active
{
transition
:
all
0
.2s
;
}
.fade-rotate-enter
,
.fade-rotate-leave-to
/*
.fade-leave-active
below
version
2
.1.8
*/
{
transform
:
rotateZ
(
45deg
);
}
</
style
>
ve-admin/admin-web/src/views/users/roles.vue
View file @
5eea9632
<!--
* @Author: 一日看尽长安花
* @since: 2020-03-29 16:00:50
* @LastEditTime: 2020-0
4-26 21:59:58
* @LastEditTime: 2020-0
5-10 14:51:34
* @LastEditors: 一日看尽长安花
* @Description:
-->
...
...
@@ -39,6 +39,15 @@
></el-cascader>
</el-form-item>
</el-col>
<el-col
:span=
"5"
>
<el-form-item
label=
"测试"
>
<sp-tree-select
width=
"170px"
:data=
"treeData"
size=
"mini"
></sp-tree-select>
</el-form-item>
</el-col>
</el-row>
<el-row
:gutter=
"10"
type=
"flex"
justify=
"end"
>
<el-col
:span=
"2"
>
...
...
@@ -111,10 +120,11 @@ import { immaditeLoadRoles } from '@/api/role';
import
{
immaditeLoadOrgs
}
from
'
@/api/org
'
;
import
{
getUserRoles
,
getUserById
,
deleteUserRoles
}
from
'
@/api/user
'
;
import
AddUserRole
from
'
./add-user-role
'
;
import
SpTreeSelect
from
'
@/components/Wrapper/SpTreeSelect
'
;
export
default
{
name
:
'
ManagerUserRole
'
,
components
:
{
Pagination
,
AddUserRole
},
components
:
{
Pagination
,
AddUserRole
,
SpTreeSelect
},
data
()
{
return
{
id
:
this
.
$route
.
params
.
id
,
...
...
@@ -135,7 +145,43 @@ export default {
},
dialogTitle
:
''
,
dialogData
:
{},
visible
:
false
visible
:
false
,
treeData
:
[
{
id
:
'
love
'
,
label
:
'
所有和你走过的风光
'
,
value
:
1
,
children
:
[
{
id
:
1
,
label
:
'
海边
'
,
value
:
11
,
children
:
[
{
id
:
5
,
label
:
'
蓬莱
'
,
value
:
111
}
]
},
{
id
:
2
,
label
:
'
森林
'
,
value
:
2
},
{
id
:
3
,
label
:
'
草原
'
,
value
:
3
},
{
id
:
4
,
label
:
'
古城
'
,
value
:
4
}
]
}
]
};
},
mounted
()
{
...
...
Write
Preview
Supports
Markdown
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