最近在使用element-ui,碰到了需要使用级联选择器的情况,研究了好久,终于实现了功能了,在这里记录一下,以便以后再次用到的时候查看。
1.需求模拟
给出如下层级表
要求实现类似下图效果
2.实现过程
加标签
sql语句
后台处理成树形json串
前台显示
1.需求模拟
给出如下层级表
project_id:项目号;
step_id:层级id;
step_name:层级名称;
all_name:层级全称(示例用,故直接写成和名称一样了);
parent_id:父级id,即隶属于哪一级,例如 DB 属于 需求调研 下的内容,以此类推;
step_num:层级数(1,2,3意为 第一层,第二层,第三层,,)
要求实现类似下图效果
2.实现过程
整个过程需要分成三步:首先 sql语句把层级表内容取出来;然后再后台对数据进行处理,处理成树形json串的形式;最后返回前台,通过js绑定到options上,进而在画面上显示。
加标签
首先需要在页面中,加入el-cascader标签,一般使用时是如下所示的结构,例如表格中的某一列需要为 级联选择器 等等。
<el-table-column header-align="center" prop="function_id" label="层级" sortable><template slot-scope="scope"><el-form-item :prop="'scaleList.'+scope.$index+'.function_id'" :rules="rules.function_id"><el-cascader v-model="scope.row.function_id" size="mini" :options="options" :props="optionProps" change-on-select placeholder="" filterable clearable></el-cascader></el-form-item></template>
</el-table-column>
sql语句
#{project_id} 为 stepEntity内传入的检索条件。
<select id="selectAllStep" parameterType="com.mydemo.entity.stepEntity" resultType="com.mydemo.util.ParentSubEntity">
SELECTSTEP_ID as subId--子级id, PARENT_ID as parentId--父级id, STEP_NAME as subName--子级name
FROMMST_STEP
WHEREPROJECT_ID = #{project_id} AND DEL_FLAG = '0'
ORDER BYSTEP_ID
</select>
后台处理成树形json串
处理之后的 alllist,已经是一个树形json串。
// 层级
List<ParentSubEntity> allStepList = this.stepMapper.selectAllStep(scaleEntity);
List<ParentSubEntity> alllist = TreeUtils.RecursiveAddress(allStepList);
tempForm.setReturnList(alllist);
public class TreeUtils {public static List<ParentSubEntity> RecursiveAddress(List<ParentSubEntity> treeNodes) {List<ParentSubEntity> trees = new ArrayList<ParentSubEntity>();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<ParentSubEntity> treeNodes) {for (ParentSubEntity it : treeNodes) {if (treeNode.getSubId().equals(it.getParentId())) {if (treeNode.getChildren() == null) {treeNode.setChildren(new ArrayList<ParentSubEntity>());}treeNode.getChildren().add(findAddressChildren(it, treeNodes));}}return treeNode;}
}
前台显示
前台的回调函数里,把后台返回的returnList的值放到画面的options内。同时还需要在optionProps内指定 el-cascader的各个元素引用返回list里的哪个值。
value:类似于id;
label:画面的下拉框中实际显示的文字。
children:子级的集合。
checkStrictly:意为可以选择任意一级菜单的内容到文本框内,而不是需要一直点击到最后一级才可以选择。老版vue需要标签中添加 change-on-select 才会有效果,新版好像不需要这样做了。
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){if(!cmMessage.hasError(scaleRegisterMaster,res)){scaleRegisterMaster.options=[];for(let i in res.data.returnList){scaleRegisterMaster.options.push(res.data.returnList[i])}}}).catch(function(error){console.log(error)scaleRegisterMaster.$message.error('初期化失敗しました。')})},}
})
以上,级联选择器的内容显示就实现了。