利用element-ui实现下拉联级选择,一级禁选、二级单选、三级多选。可进行搜索,显示搜索条数,可全部清除。
html
<div class="check-outer">
<!--搜索框-->
<el-input
clearable
@click.native="()=>showTree = true"
placeholder="输入关键字进行过滤"
@change="valueChange"
v-model="filterText">
</el-input>
<!--显示条数-->
<i v-if="firstLength>0">+{{ firstLength }}</i>
<el-tree
v-show="showTree"
:class="'filter-tree'"
node-key="num"
show-checkbox
accordion
:data="data"
:props="defaultProps"
@check="treeCheck"
:filter-node-method="filterNode"
ref="tree">
</el-tree>
</div>
判断一级节点并禁选
computed: {
defaultProps() {
return {
children: 'children',
value: 'num',
label: 'label',
disabled: (data, node) => {
// 判断是否为一级节点
return data && node.level === 1
}
}
}
},
这段用于搜索功能
watch: {
filterText(val) {
if (!this.checkTree) {
this.$refs.tree.filter(val)
}
},
}
data () {
return {
data: [{
num: 1,
label: '一级 1',
children: [{
num: 2,
label: '二级 1-1',
children: [{
num: 4,
label: '三级 1-1-1'
}, {
num: 5,
label: '三级 1-1-2'
},{
num: 6,
label: '三级 1-1-1'
}, {
num: 7,
label: '三级 1-1-2'
}]
},{
num: 3,
label: '二级 2-1',
children: [{
num: 8,
label: '三级 2-1-1'
}, {
num: 9,
label: '三级 2-1-2'
}]
}]
}],
showTree: false, // 下拉选择框的显示
fileIdListFirst: [], // 选择的节点id(num),用于传给后端
firstLength: '', // 显示条数
checkTree: false, // 判断是否点击过节点 为了搜索
filterText: '', // 搜索框绑定数据
nodeChange: 0, // 判断段级id是否发生变化
instantIdFirst: '', // 一级id
}
}
treeCheck(data, list) {
let fileIdListFirst = []
// data 该节点所对应的对象、list 树目前的选中状态对象
// 选中事件在选中后执行,当lis中有两个选中时,使用setCheckedKeys方法,选中一个节点
// 单选实现 段级
if (data.children) {
if (list.checkedKeys.length > 0) {
// 段级单选实现
this.$refs.tree.setCheckedNodes([data])
} else {
// 取消当前选中节点
this.$refs.tree.setCheckedKeys([])
}
// 段级id给this.nodeChange 主要用于判断选的叶子节点的父节点是否变化
this.nodeChange = this.$refs.tree.getNode(data).id
this.instantIdFirst = this.$refs.tree.getNode(data).parent.data.id // 一级id
} else { // 叶子节点 如果段级节点发生变化,则清空所有选择的节点
if (this.nodeChange !== this.$refs.tree.getNode(data).parent.id) {
this.$refs.tree.setCheckedKeys([]) // 清空已存在的所有节点,
this.$refs.tree.setCheckedNodes([data])
}
// 当前叶子节点的父级id为段级,段级id给this.nodeChange 主要用于判断选的叶子节点的父节点是否变化
this.nodeChange = this.$refs.tree.getNode(data).parent.id
this.instantIdFirst = this.$refs.tree.getNode(data).parent.parent.data.id // 一级id
}
if (this.$refs.tree.getCheckedNodes().length > 0) { // 所选节点的id赋给fileIdListFirst,传给后台用作对比数据
if (this.$refs.tree.getCheckedNodes()[0].children) { // 父级
this.$refs.tree.getCheckedNodes().forEach((v, index) => {
if (index > 1) {
fileIdListFirst.push(v.id) // 用于对比的数组
this.filterText = this.$refs.tree.getCheckedNodes()[2].label // 选择的第一条数据放进搜索框,其他数据条数用数字显示
}
})
} else { // 子级
this.$refs.tree.getCheckedNodes().forEach(v => {
fileIdListFirst.push(v.id) // 用于对比的数组
this.filterText = this.$refs.tree.getCheckedNodes()[0].label // 选择的第一条数据放进搜索框,其他数据条数用数字显示
})
}
this.checkTree = true // 判断是否点击过节点 为了搜索
this.fileIdListFirst = fileIdListFirst
if (this.fileIdListFirst.length > 0) {
this.firstLength = this.fileIdListFirst.length // 显示的数据条数
}
} else {
this.firstLength = '' // 清空选择的数据条数显示
this.filterText = '' // 清空搜索框
this.checkTree = false // 数据清空后可以搜索
}
},
用于筛选
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
css
<style scoped lang="scss">
.check-outer{
width: 250px;
position: relative;
border: 1px solid #dbdbdb;
border-radius: 5px;
/deep/ .el-input--mini .el-input__inner{
border: 0;
padding-right: 55px;
}
i{
position: absolute;
right: 28px;
font-size: 0.65rem;
font-style: normal;
top: 6px;
border: 1px solid #dfe2e8;
padding: 2px;
border-radius: 3px;
}
}
</style>