最近在使用element-ui,碰到了需要使用级联选择器的情况,研究了好久,终于实现了功能了,在这里记录一下,以便以后再次用到的时候查看。
1.需求模拟
给出如下层级表
要求实现类似下图效果
2.实现过程
sql语句
后台处理成树形json串
前台显示
加标签
样式问题
project_id:项目号;
step_id:层级id;
step_name:层级名称;
all_name:层级全称(示例用,故直接写成和名称一样了);
parent_id:父级id,即隶属于哪一级,例如 DB 属于 需求调研 下的内容,以此类推;
step_num:层级数(1,2,3意为 第一层,第二层,第三层,,)
整个过程需要分成三步:首先 sql语句把层级表内容取出来;然后在后台对数据进行处理,处理成树形json串的形式;最后返回前台,通过js绑定到options上,进而在画面上显示。
#{project_id} 为 stepEntity内传入的检索条件。
resultType的Entity内容如下
package XXX;
import java.util.List;
public class ParentSubEntity {
/** 父ID */
private String parentId;
/** 子ID */
private String subId;
/** 子NAME */
private String subName;
/** 子TREE */
private List children;
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getSubId() {
return subId;
}
public void setSubId(String subId) {
this.subId = subId;
}
public String getSubName() {
return subName;
}
public void setSubName(String subName) {
this.subName = subName;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
}
处理之后的 alllist,已经是一个树形json串。
// 层级
List allStepList = this.stepMapper.selectAllStep(scaleEntity);
List alllist = TreeUtils.RecursiveAddress(allStepList);
tempForm.setReturnList(alllist);
public class TreeUtils {
public static List RecursiveAddress(List treeNodes) {
List trees = new ArrayList();
for (ParentSubEntity treeNode : treeNodes) {
if ("".equals(treeNode.getParentId()) || null == treeNode.getParentId()) {
trees.add(findAddressChildren(treeNode, treeNodes));
}
}
return trees;
}
//递归查找地址子节点
public static ParentSubEntity findAddressChildren(ParentSubEntity treeNode, List treeNodes) {
for (ParentSubEntity it : treeNodes) {
if (treeNode.getSubId().equals(it.getParentId())) {
if (treeNode.getChildren() == null) {
treeNode.setChildren(new ArrayList());
}
treeNode.getChildren().add(findAddressChildren(it, treeNodes));
}
}
return treeNode;
}
}
前台的回调函数里,把后台返回的returnList的值放到画面的options内。同时还需要在optionProps内指定 el-cascader的各个元素引用返回list里的哪个值。
value:类似于id;
label:画面的下拉框中实际显示的文字。
children:子级的集合。
checkStrictly:意为可以选择任意一级菜单的内容到文本框内,而不是需要一直点击到最后一级才可以选择。老版element-ui需要标签中添加 change-on-select 才会有效果,新版好像不需要这样做了。
js
var scaleRegisterMaster = new Vue({
el: "#app",
data: {
scaleForm: {
},
options:[],
optionProps: {
value: 'subId',
label: 'subName',
children: 'children',
checkStrictly: true
},
},
created: function(){
// 初始化
this.init();
},
methods: {
// 初始化
init : function(){
axios.post("/api/scale/Init",this.scaleForm
).then(function(res){
scaleRegisterMaster.options=[];
for(let i in res.data.returnList){
scaleRegisterMaster.options.push(res.data.returnList[i])
}
}).catch(function(error){
scaleRegisterMaster.$message.error('初始化失败!')
})
},
}
})
如果某一级内容过长,导致组件的子选择框过长,超出页面宽度,可以在css文件加入如下代码限制长度
.el-cascader-menu{
width:180px;
}
加了上面代码后,过长的内容默认后缀省略号,如果想使用滚动条的方式,可在css文件加如下代码。
主要起作用的为 overflow: initial; 其余为样式调整。
.el-cascader-menu__item {
font-size: 12px;
padding: 8px 20px;
position: relative;
white-space: nowrap;
overflow: initial;
text-overflow: ellipsis;
color: #606266;
height: 34px;
line-height: 1.5;
-webkit-box-sizing: border-box;
box-sizing: border-box;
cursor: pointer;
outline: 0;
}
以上,级联选择器的内容显示就实现了。