当前位置 博文首页 > 程序员A的博客:ElementUI下拉树带搜索
<template>
<div>
<el-select v-model="form" placeholder="请选择" multiple collapse-tags size="small"
@focus="Focus" @change="translate" :clearable="clearable">
<el-option :value="value" disabled >
<el-input style="margin-left: 2px;margin-right: 15px;width: 94%;" placeholder="输入关键字进行过滤" v-model="filterText" clearable size="small"></el-input>
<div>
<el-tree
:filter-node-method="filterNode"
:data="childData"
show-checkbox
:props="defaultProps"
ref="eltree"
:node-key="code"
:default-expand-all="false"
@check-change="checkchange"
></el-tree>
</div>
</el-option>
<div style="display:flex;justify-content:center;align-items:center;margin-top:10px;">
<!-- <el-button @click="sure" size="small">确定</el-button> -->
<el-button @click="all" size="small">全选</el-button>
<el-button @click="clear" size="small">清空</el-button>
</div>
</el-select>
</div>
</template>
<script>
/*
childData为传入的数组
name为下拉框上面多选的栏目的名字
code为栏目名字中的编码
chidldName为传入的子节点的名称
clearable 是否在选择框中显示全部删除按钮
treedata:
[{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1'
}]
}]
比如:上面的数据,
使用组件时绑定字段名称如下
code: 'id',//树形节点的编码名称
name: 'label',//树形节点的名称
childrenName: "children",//子节点的名称
treeHeight: "150px" //树形下拉高度
chooseparent:是否选择父节点返回值
*/
var that;
export default {
props:{
childData:Array,
name:String,
code:String,
childrenName:String,
clearable:{
type:Boolean,
default:false
},
chooseparent:{ //默认等于false,只是获取叶子节点值
type:Boolean,
default:false
},
treeHeight:{//树形下拉的高度
type:String,
default:'150px'
},
selectFocus:Function//选择框获取焦点事件
},
data() {
return {
value: "",//默认值
defaultProps: {
children: this.childrenName,
label: this.name
},
form: [],
codeForm:[],
isAll:false,
x:true,
list:[],
filterText:''
};
},
watch: {
filterText(val) {
this.$refs.eltree.filter(val);
}
},
created () {
that = this;
},
methods: {
//下拉框获取焦点
Focus(){
if(typeof(this.selectFocus)==='function'){ this.selectFocus();}
},
filterNode(value, data) {
if (!value) return true;
return data[this.name].indexOf(value) !== -1;
},
//树形节点选择
checkchange(obj,bChecked,bChildChecked){
this.sure();
},
//确定,并返回一个数组,里面是前面传入的遍历的code
sure() {
let list = this.$refs.eltree.getCheckedNodes();
this.form = [];
this.codeForm = [];
for (let a in list) {
//是否选择父节点
var nodeObj = eval("list[a]");
this.form.push(nodeObj[this.name]);
//是否选择父节点
if(!this.chooseparent && nodeObj.children){continue;}
this.codeForm.push(nodeObj[this.code]);
}
//触发父组件的data方法,将选择的数据赋值
this.$emit('data',this.codeForm)
this.x=true;
},
//清空
clear() {
this.form = [];
this.filterText='';
this.$refs.eltree.setCheckedKeys([]);
},
//全选
all(){
if(this.isAll==false){
this.$refs.eltree.setCheckedNodes(this.childData);
this.isAll=true
}else{
this.$refs.eltree.setCheckedKeys([]);
this.isAll=false
}
},
//下拉框选择到的数据进行删除后,树前面的勾选取消操作
translate(val){
let list2=[];
if(this.x==true){
this.list=this.$refs.eltree.getCheckedNodes();
for(let i=1;i<this.list.length;i++){
list2.push(this.list[i])
}
this.list=list2
this.x=false;
}else{
for(let i=1;i<this.list.length;i++){
list2.push(this.list[i])
}
this.list=list2
}
this.$refs.eltree.setCheckedNodes(list2);
this.codeForm=[]
for(let a in list2){
this.codeForm.push(eval("list2[a]"+'.'+this.code));
}
this.$emit('data',this.codeForm)
}
}
};
</script>
<style scoped>
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
height: auto;
max-height: 274px;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected{
font-weight: normal;
}
ul li >>>.el-tree .el-tree-node__content{
height:auto;
padding: 0 20px;
}
.el-tree-node__label{
font-weight: normal;
}
.el-tree >>>.is-current .el-tree-node__label{
color: #409EFF;
font-weight: 700;
}
.el-tree >>>.is-current .el-tree-node__children .el-tree-node__label{
color:#606266;
font-weight: normal;
}
</style>
使用:
<template>
<div>
<el-button @click="GetSelect">获取选中</el-button>
<selectTree :childData="optionData" :name="name" :code="code" :childrenName="childrenName" @data="getData"
:chooseparent="true">
</selectTree>
</div>
</template>
<script>
import selectTree from "../components/SelectTree.vue";
var that;
export default {
components: {
selectTree
},
data() {
return {
selectNodeData: [], //选中的树形节点
code: 'id', //树形节点的编码名称
name: 'name', //树形节点的名称
childrenName: "children", //子节点的名称
list:[ //模拟服务器返回的数据
{id:1,parentId:0,name:"一级菜单A",rank:1},
{id:2,parentId:0,name:"一级菜单B",rank:1},
{id:3,parentId:0,name:"一级菜单C",rank:1},
{id:4,parentId:1,name:"二级菜单A-A",rank:2},
{id:5,parentId:1,name:"二级菜单A-B",rank:2},
{id:6,parentId:2,name:"二级菜单B-A",rank:2},
{id:7,parentId:4,name:"三级菜单A-A-A",rank:3}
]
};
},
computed:{
optionData(){
return this.tranTreeData('id','parentId');
}
},
created() {
that = this;
},
methods: {
getData(val) {//将选中的节点赋值到此变量
this.selectNodeData = val
},
GetSelect() { //获取选中
console.warn(that.selectNodeData)
},
tranTreeData(childName,parentName){//模拟将服务器数据转tree数据
let cloneData = JSON.parse(JSON.stringify(this.list)) // 对源数据深度克隆
return cloneData.filter(father=>{ // 循环所有项,并添加children属性
let branchArr = cloneData.filter(child=>father[childName] == child[parentName]); // 返回每一项的子级数组
branchArr.length>0 ? father.children=branchArr : '' //给父级添加一个children属性,并赋值
return father[parentName]==0; //返回第一层
});
}
}
};
</script>
<style>
/* 选择组件设置隐藏超出组件的值 */
.el-select__tags {
flex-wrap: nowrap;
overflow: hidden;
}
</style>
参考网上许多人的写法修改了一下。