针对树形控件做挑选框
单选效果:

image.png
多选效果

image.png
<template>
<div>
<el-input
v-if="curActionType === 'view'"
v-model="value.name"
:style="{ width: componentWidth }"
disabled
/>
<el-popover
v-else
v-model="showSelection"
placement="bottom"
trigger="click"
>
<el-input
slot="reference"
v-model="value.name"
:style="{ width: componentWidth }"
:placeholder="`请选择所属${showName}`"
readonly
/>
<div>
<el-input
v-model="filterText"
:placeholder="`请输入${showName}`"
class="mb15"
v-if="showSearch"
/>
<el-tree
ref="tree"
:data="treeData"
:node-key="rowKeys.id"
:show-checkbox="isMulti"
:default-expanded-keys="[1]"
:props="defaultProps"
:filter-node-method="filterNode"
@check-change="handleCheckChange"
@current-change="handleCurrentChange"
:highlight-current="!isMulti"
/>
</div>
</el-popover>
</div>
</template>
<script>
export default {
name: 'TreeSelect',
props: {
value: {
type: Object,
default: () => ({
id: '',
name: ''
})
},
rowKeys: {
type: Object,
default: () => ({
id: 'id',
name: 'name',
children: 'children',
parent: 'parent'
})
},
treeData: {
type: Array,
default: () => []
},
componentWidth: {
type: String,
default: '250px'
},
showName: {
type: String,
default: ''
},
valueType: {
type: String,
default: 'all' // all,parent,son;选择all时,所选中的父子节点都返回;选择parent的时候,当前父节点下所有子节点都被选择时,只返回父节点;选择son的时候,当前父节点下所有子节点都被选择时,过滤父节点
},
isMulti: {
type: Boolean,
default: true
},
showSearch: {
type: Boolean,
default: true
}
},
data() {
return {
multipleSelection: [],
showSelection: false,
filterText: ''
}
},
computed: {
defaultProps() {
return {
children: this.rowKeys.children,
label: this.rowKeys.name
}
}
},
watch: {
filterText(val) {
this.$refs.tree.filter(val)
}
},
mounted() {
if (this.isMulti) {
this.multiReset()
} else {
this.singleReset()
}
},
methods: {
multiReset() {
if (this.curActionType === 'view') {
return false
}
if (this.value.id) {
this.$nextTick(() => {
this.$refs.tree.setCheckedKeys(this.value.id.split(','))
})
} else {
this.$nextTick(() => {
this.$refs.tree.setCheckedKeys([])
})
}
},
// 单选设置当前选中节点
singleReset() {
console.log(this.value.id, this.$refs.tree.setCurrentKey)
if (this.value.id) {
this.$refs.tree.setCurrentKey(this.value.id)
}
},
// 树菜单搜索
filterNode(value, data) {
if (!value) return true
return data[this.rowKeys.name].indexOf(value) !== -1
},
// 选择
handleCheckChange() {
const checkNodes = this.$refs.tree.getCheckedNodes()
if (this.valueType === 'all') {
this.multipleSelection = checkNodes
} else if (this.valueType === 'son') {
this.multipleSelection = checkNodes.filter((item) => {
return !item.children || item.children.length === 0
})
} else {
const parentNodes = checkNodes
.filter((item) => {
return item.children && item.children.length > 0
})
.map((i) => i[this.rowKeys.id])
let result = []
for (const j of checkNodes) {
if (!parentNodes.includes(j[this.rowKeys.parent])) {
result.push(j)
}
}
this.multipleSelection = result
}
this.submit()
},
// 多选提交选择信息
submit() {
const checkedIds = this.multipleSelection
.map((item) => item[this.rowKeys.id])
.join(',')
const checkedNames = this.multipleSelection
.map((item) => item[this.rowKeys.name])
.join(',')
this.$emit('input', { id: checkedIds, name: checkedNames }) // 传值给父组件
},
// 单选提交选择信息
handleCurrentChange(data, node) {
if (this.curActionType === 'view') {
return false
}
if (!this.isMulti) {
this.$emit('input', {
id: data[this.rowKeys.id],
name: data[this.rowKeys.name]
})
} // 传值给父组件
}
}
</script>
isMulti是单选多选标志,为true时是多选,拥有checkbox,否则为单选。
当多选时,无需高亮,只需要设置所选中数据前的checkbox为选中状态;设置row-key值,并且在created/mounted时,引用element-UI自带的函数setCheckedKeys
this.$refs.tree.setCheckedKeys(this.value.id.split(','))
当单选时,需要高亮,除了要设置设置row-key值,并且在created/mounted时,引用element-UI自带的函数setCurrentKey外,还需要设置:highlight-current="true"
this.$refs.tree.setCurrentKey(this.value.id)
使用样例
<template>
<div class="menuManagement">
<tree-select
v-model="test"
:row-keys="{
id: 'deptId',
name: 'deptName',
parent: 'deptParentId',
children: 'children'
}"
show-name="业务组"
value-type="all"
:tree-data="deptData"
:is-multi="true"
>
</tree-select>
</div>
</template>
<script>
import TreeSelect from '@/components/TreeSelect/index.vue'
export default {
name: 'menuManagement',
components: { TreeSelect },
data() {
return {
test: {
id: '1',
name: '民生业务组'
},
deptData: [
{
deptId: 1,
deptName: '民生业务组',
deptParentId: 0,
deptCode: null,
deptDesc: null,
createUserId: 1,
createTime: '2019-09-26 21:19:45',
updateUserId: 1,
updateTime: '2019-12-05 11:31:55',
children: [
{
deptId: 3,
deptName: '出入境',
deptParentId: 1,
deptCode: null,
deptDesc: '出入境',
createUserId: 1,
createTime: '2019-09-26 21:19:51',
updateUserId: 1,
updateTime: '2019-12-20 14:23:49',
children: null,
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 10,
deptName: '治安',
deptParentId: 1,
deptCode: null,
deptDesc: '治安',
createUserId: 1,
createTime: null,
updateUserId: 1,
updateTime: '2019-12-19 16:20:56',
children: [
{
deptId: 50,
deptName: '治安1',
deptParentId: 10,
deptCode: null,
deptDesc: '1',
createUserId: 18,
createTime: '2019-12-27 11:31:04',
updateUserId: null,
updateTime: null,
children: null,
deptParentName: '治安',
deleteFlag: null
},
{
deptId: 588,
deptName: '治安2',
deptParentId: 10,
deptCode: null,
deptDesc: '1',
createUserId: 18,
createTime: '2019-12-27 11:31:04',
updateUserId: null,
updateTime: null,
children: [
{
deptId: 5881,
deptName: '治安2-1',
deptParentId: 588,
deptCode: null,
deptDesc: '1',
createUserId: 18,
createTime: '2019-12-27 11:31:04',
updateUserId: null,
updateTime: null,
children: null,
deptParentName: '治安',
deleteFlag: null
},
{
deptId: 5882,
deptName: '治安2-2',
deptParentId: 588,
deptCode: null,
deptDesc: '1',
createUserId: 18,
createTime: '2019-12-27 11:31:04',
updateUserId: null,
updateTime: null,
children: null,
deptParentName: '治安',
deleteFlag: null
}
],
deptParentName: '治安',
deleteFlag: null
}
],
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 12,
deptName: '交管',
deptParentId: 1,
deptCode: null,
deptDesc: '交管',
createUserId: 1,
createTime: '2019-09-27 16:24:31',
updateUserId: 2,
updateTime: '2019-12-25 12:51:28',
children: [
{
deptId: 122,
deptName: '交管1',
deptParentId: 12,
deptCode: null,
deptDesc: '1',
createUserId: 18,
createTime: '2019-12-27 11:31:04',
updateUserId: null,
updateTime: null,
children: null,
deptParentName: '交管',
deleteFlag: null
},
{
deptId: 133,
deptName: '交管2',
deptParentId: 12,
deptCode: null,
deptDesc: '1',
createUserId: 18,
createTime: '2019-12-27 11:31:04',
updateUserId: null,
updateTime: null,
children: null,
deptParentName: '交管',
deleteFlag: null
}
],
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 13,
deptName: '监管',
deptParentId: 1,
deptCode: null,
deptDesc: '监管',
createUserId: 1,
createTime: '2019-09-27 16:52:37',
updateUserId: 2,
updateTime: '2019-12-23 11:07:14',
children: null,
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 14,
deptName: '科信',
deptParentId: 1,
deptCode: null,
deptDesc: '科信',
createUserId: 1,
createTime: null,
updateUserId: 2,
updateTime: '2019-12-23 11:07:33',
children: null,
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 15,
deptName: '法制总队',
deptParentId: 1,
deptCode: null,
deptDesc: '法制总队',
createUserId: 1,
createTime: null,
updateUserId: 1,
updateTime: '2019-12-19 16:50:58',
children: null,
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 16,
deptName: '其他业务警种',
deptParentId: 1,
deptCode: null,
deptDesc: '其他业务警种',
createUserId: 1,
createTime: null,
updateUserId: 1,
updateTime: '2019-12-19 16:57:44',
children: null,
deptParentName: '民生业务组',
deleteFlag: null
},
{
deptId: 45,
deptName: 'sad',
deptParentId: 1,
deptCode: null,
deptDesc: 'asd',
createUserId: 1,
createTime: '2019-12-20 14:24:05',
updateUserId: null,
updateTime: null,
children: null,
deptParentName: '民生业务组',
deleteFlag: null
}
],
deptParentName: null,
deleteFlag: null
}
]
}
}
}
</script>
<style lang="scss" scoped></style>