最近在写代码的时候遇到一个需求,就是需要试用下拉菜单完成二级菜单选择、甚至有三级的菜单选择:
UI提出此功能需要有以下三个要点:
<template>
<div class="demo">
<elTree :list="options" :defaultProps="defaultProps" @getdetail="getdetail" :selectType="selectType"> </elTree>
</div>
</template>
<script>
import elTree from './elTree.vue'
export default {
components: {
elTree,
},
data() {
return {
options: [
{
id: 1,
label: '一级 2',
value: '一级2',
disabled: false,
children: [
{
id: 3,
label: '二级 2-1',
value: '二级2-1',
disabled: false,
children: [
{
id: 4,
label: '三级 3-1-1',
value: '三级3-1-1',
disabled: false,
},
{
id: 5,
label: '三级 3-1-2',
value: '三级3-1-2',
disabled: false,
},
],
},
{
id: 2,
label: '二级 2-2',
value: '二级2-2',
disabled: true,
children: [
{
id: 6,
label: '三级 3-2-1',
value: '三级3-2-1',
disabled: false,
},
{
id: 7,
label: '三级 3-2-2',
value: '三级3-2-2',
disabled: false,
},
],
},
],
},
],
// 数据格式化====必填
defaultProps: {
children: 'children',
label: 'label',
value: 'value',
},
//单选或者复选
selectType: 'single',//multiple为多选
}
},
methods: {
//获取勾选数据
getdetail(val) {
console.log(val, '222222222')
},
},
}
</script>
<template>
<div class="app-container caseManagementIndex scrollcontainer scrollcontainer_auto" ref="caseManagementIndex" v-if="list.length > 0">
<el-select v-model="value" filterable :multiple="multiple" placeholder="请选择" :popper-append-to-body="false" :filter-method="assetsTypeFilter">
<el-option :value="selectTree" class="setstyle" disabled>
<el-tree
:data="list"
:props="defaultProps"
ref="tree"
node-key="id"
show-checkbox
check-strictly
:expand-on-click-node="false"
check-on-click-node
@check-change="checkChangeClick"
:filter-node-method="filterNode"
></el-tree>
</el-option>
</el-select>
</div>
</template>
<script>
export default {
name: 'caseManagementIndex',
// import引入的组件需要注入到对象中才能使用PopupTreeInput
components: {},
props: {
list: {
type: Array,
default: () => [],
},
defaultProps: {
type: Object,
default: {
//children: 'children',
//label: 'label',
},
},
selectType: {
type: String,
default: 'multiple',
},
},
data() {
// 这里存放数据
return {
value: [],
selectTree: [],
multiple: true,
}
},
// 监听属性 类似于data概念
computed: {},
// 监控data中的数据变化
watch: {},
// 生命周期 - 创建完成(可以访问当前this实例)
created() {},
// 生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
console.log('flatten(fromData)', this.flatten(this.list))
this.selectTree = this.flatten(this.list)
},
// 方法集合
methods: {
flatten(arr) {
return [].concat(
...arr.map((item) => {
if (item.children) {
let arr = [].concat(item, ...this.flatten(item.children))
delete item.children
return arr
}
return [].concat(item)
}),
)
},
assetsTypeFilter(val) {
// 下拉框调用tree树筛选
//console.log(this, val)
this.$refs.tree.filter(val)
},
checkChangeClick(data, self, child) {
console.log(data, self, child, this.selectType)
if (this.selectType == 'multiple') {
let datalist = this.$refs.tree.getCheckedNodes()
//console.log('datalist', datalist)
this.value = []
datalist.forEach((item) => {
this.value.push(item.label)
})
let values = datalist.map((item) => {
return item.value
})
this.$emit('getdetail', datalist)
} else {
if (self) {
this.$refs.tree.setCheckedNodes([data])
this.multiple = false
this.value = data.label
this.$emit('getdetail', data)
}
}
},
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
},
}
</script>
<style lang="scss">
.setstyle {
min-height: 200px;
padding: 0 !important;
margin: 0;
overflow: auto;
cursor: default !important;
}
</style>
<style lang="scss" scoped></style>
以上el-select和el-tree实现单选/复选/搜索组件封装就好啦。
利用属性:filterable +方法 filter-method实现
利用**:multiple="multiple"和selectType进行判断,不同的情况下,勾选的结果是单选还是多选,走不通的业务逻辑
如果你觉得本文写的不错的话,记得收藏、关注和点赞哟,