目录
- 简单看看el-transfer穿梭框
- 实现思路
- 完整代码
- 结果图
简单看看el-transfer穿梭框
这是一个简单的el-transfer穿梭框,截图自element官网 link 列表1为待选数据,列表2为已选数据,通过选中列表中的数据,点击左移或右移按钮,就可以进行数据的选择和取消选择了。
要注意的是,列表1和列表2的数据其实来源于同一个数组对象,列表1是全部的数据列表,列表2是从列表1中选出来的,这很好理解。但是在实际应用中,有可能需要根据搜索条件的不同,左边的数据是在不断变化的。比如从后台传来的数据要分类,我每次只选择一个分类的数据在左边列表,由于右边列表的数据和左边同源,那么我每次右边要刷新的时候,左边也肯定是要刷新的。所以如果需要展示所有分类的已选数据,这个穿梭框就是不适用的。
还有一个会碰到的问题是,左边的数据源data中,是可以有很多属性的,比如id,和我刚刚提到的分类,而右边得到的数据value是有且只有id这一个属性的,那就不是那么灵活。
能否有一个穿梭框,在具备基本穿梭框功能的同时,能保持右边一直展现所有的已选数据,并且右边的数据也可以有很多属性。
实现思路
1.布局:
首先,穿梭框就是要有一左一右两个div用来放我们的数据,div中的数据用el-tree。要有四个按钮用来绑定事件。
2.功能:
右移add增加选项功能:对左边数据选择完毕之后,按下右移按钮,左边div中相应的选项要禁用,右边div中要出现相应的被选数据。
全部右移addAll功能:按下全部右移按钮,左边数据要全部禁用,右边要出现所有的左边数据,并且要跳过已经被选择过的数据。
左移del功能:右边的div,选择完毕之后,按下左移按钮,左边div中相应数据恢复可选状态,并且右边被选的选项要删除。
全部左移delAll功能:按下全部左移按钮,左边div中全部选项恢复可选状态,并且右边清空。
完整代码
新建一个vue+element项目,直接复制代码过去就能运行
<template>
<div class="transfer">
<el-form style="width:800px;">
<el-row>
<el-col :span="10">
<el-input placeholder="这里可以放一些搜索的条件"></el-input>
</el-col>
<el-col :span="4">
<el-button @click="setData">查询</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="10">
<!-- 这里是左边的待选框 -->
<div class="box" style="overflow:scroll; height:500px; border:1px">
<el-tree
:data="leftTree"
node-key="id"
ref="leftTree"
show-checkbox
default-expand-all
:props="defaultLeftProps"
check-on-click-node>
</el-tree>
</div>
</el-col>
<el-col :span="4">
<div style="margin:40px"><el-button icon="el-icon-arrow-right" @click="add"></el-button></div>
<div style="margin:40px"><el-button icon="el-icon-d-arrow-right" @click="addAll"></el-button></div>
<div style="margin:40px"><el-button icon="el-icon-arrow-left" @click="del"></el-button></div>
<div style="margin:40px"><el-button icon="el-icon-d-arrow-left" @click="delAll"></el-button></div>
</el-col>
<el-col :span="10">
<!-- 这里是右边的已选框 -->
<div class="box" style="overflow:scroll; height:500px; border:1px">
<el-tree
:data="rightTree"
node-key="id"
ref="rightTree"
show-checkbox
default-expand-all
:props="defaultProps"
check-on-click-node>
</el-tree>
</div>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
leftTree:[], //左边树 待选数据
defaultLeftProps:{
children: "children",
label: "name",
id: "id",
disabled: "disabled" //表示是否禁用的状态
},
rightTree:[], //右边树 已选数据
defaultProps:{
children: "children",
label: "name",
id: "id",
}
};
},
created(){
this.init();
},
methods: {
init(){
//初始化的时候分别获取一下左边树和右边树
this.getRightTree();
this.getLeftTree();
},
//这里是已选数据的获取方法,应该从后台拿的,这里本地模拟一下
getRightTree(){
this.rightTree = [{id:1, name:'选项1'}];
},
//获取待选数据的方法
getLeftTree(){
this.leftTree = [
{id:1, name:'选项1'},
{id:2, name:'选项2'},
{id:3, name:'选项3'},
{id:4, name:'选项4'},
{id:5, name:'选项5'},
{id:6, name:'选项6'},
{id:7, name:'选项7'}
];
//对右边树中已有的指标,左边树对应的节点要设置禁用
for(var i=0; i<this.leftTree.length; i++){
for(var j=0; j<this.rightTree.length; j++){
if(this.leftTree[i].id == this.rightTree[j].id){
this.leftTree[i].disabled = true;
}
}
}
},
//查询页面的方法
setData(){
this.getLeftTree();
},
add(){
var addArr = [];
let res = this.$refs.leftTree.getCheckedNodes(); //取得所有被选中的左边的数据
for(var i=0; i<res.length; i++){
addArr.push({
id: res[i].id,
name: res[i].name
})
res[i].disabled = true; //将添加过的选项设置禁用
}
for(var i=0; i<addArr.length; i++){ //将选择的选项push进右边树里
this.rightTree.push(addArr[i]);
}
this.$refs.leftTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
this.$refs.rightTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
},
addAll(){
this.$refs.leftTree.setCheckedNodes(this.leftTree);//选中所有左边的数据
let res = this.$refs.leftTree.getCheckedNodes();//取得所有被选中的左边的数据
for(var i=0; i<res.length; i++){
if(res[i].disabled == true){ //如果是已经被选中过的,即已经被禁用的节点,跳过这次push
continue;
}
this.rightTree.push({
id: res[i].id,
name: res[i].name
});
res[i].disabled = true; //将添加过的选项设置禁用
}
this.$refs.leftTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
this.$refs.rightTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
},
del(){
var arr = [];
let res = this.$refs.rightTree.getCheckedNodes();//取得所有被选中的右边的数据
for(var i=0; i<res.length; i++){
arr.push({
id: res[i].id,
name: res[i].name
})
}
for(var i=0; i<arr.length; i++){ //根据选中的选项删除rightTree中的数据
for(var j=0; j<this.rightTree.length; j++){
if(arr[i].id == this.rightTree[j].id){
this.rightTree.splice(j,1);
j--;
}
}
}
for(var i=0; i<arr.length; i++){ //将左边树中,被删除的选项恢复可勾选状态
for(var j=0; j<this.leftTree.length; j++){
if(arr[i].id == this.leftTree[j].id){
this.leftTree[j].disabled = false;
}
}
}
this.$refs.leftTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
this.$refs.rightTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
this.setData();//刷新一下
},
delAll(){
this.rightTree = [];
for(var i=0; i<this.leftTree.length; i++){
this.leftTree[i].disabled = false;
}
this.$refs.leftTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
this.$refs.rightTree.setCheckedKeys([]); //将之前选中的节点清除勾选状态
this.setData();//刷新一下
},
}
};
</script>
结果图