今日,在vue项目中使用饿了么的Cascader级联选择器时,遇到了一个问题,情景时这样的, 数据是从后台拿到的,前端要做出的效果是当满足某些条件时,某些选项禁止选中。花了很长时间解决这个问题,于是写这篇文章记录解决方案。

element ui级联查询 element级联选择回显_级联框回显问题

如上图所示,假如 ecs为v类型,则不允许选中其子节点。 按照以往经验,简单分析,应该是树的这个节点添加一个字段就能实现禁用,果不其然,去饿了么官网查看得知(Cascader级联选择器),添加一个disabled属性即可。

于是对后端返回的数据进行如下处理:

getTreeList(val) {
			//对 treeList 进行递归操作,禁止选中t和v
			val &&
                val.forEach(item => {
                	if (item.type == "t" || item.type == "v") {
                		item.disabled = true; // 如果类型为t或者v,就增加禁用选项
                	}
                	if (item.children) {
                        this.getTreeList(item.children);
                    }
                });
   return val ;
}

 如上代码显示,递归遍历treeList ,将所有节点及其子节点进行遍历,判断type属性是否为t或者v ,如果是 就给该节点增加disabled属性,并设置为true,  item是一个json对象,里面并没有disabled字段,显式的指定item.disabled=true ,就给该json对象中增加了disabled属性, 并设为true。(一下子暴露了对js中的对象的理解并不是很透彻。。) 。

这样就解决了我的需求, 但是这里仍想记录一下我当时的做法。

for(let elem of val.values()){
			   if(elem.type=="t"|| elem.type=="v"){
			     // elem={
			     //   ...elem,
			     //   disabled: true
			     // };
			    elem.disabled= true;
			   }

			   if(elem.children ){
			     this.getTreeList(elem.children);
			   }
			}
			return val ;

}

注意我注释的部分,使用三元运算符, elem={ ...elem ,disabled:true},原以为没问题,但是检测发现,使用该方式并没用,查下了资料并没有找到原因。希望读完这篇文章的哥们指点一下,在下感激不尽!

附上部分页面代码(有删改,至于为什么你懂。。):

<el-cascader
        v-model="pid"
        :options="this.treeList"
        :props="moduleProps"
        change-on-select
        ref="cascader"
   ></el-cascader>

data(){
  return (){
    moduleProps: {
		label: "name",
		value: "id",
		children: "children"
	}
  }
},
computed: {
   treeList() {
     return this.TestController.allTree.data;
   } ,
}

另外附上,表单编辑时,级联框回显的解决方案:  官方文档指出,默认值通过数组的方式指定,即我们通过数组方法给出选中节点的所有的父节点,就能回显。回到本例中,原有数据结构是一个tree ,节点下面有子节点,子节点下面还有节点,为了拿到选中节点的父节点,我在定义了一个变量,一维json数组 idAndParent=[] ,然后对原有的数据结构(树)进行遍历, 取出所有的节点id和父节点id(即该节点的parentId),放进这个一维数组,然后在通过选中节点的id,去一维数组中查找该id,进而拿到paretnId 这样通过递归,就能拿到选中节点的所有父节点,在外部定义数组,每次找到父节点,就把它push到该数组中。下面附上代码:

getIdAndParent(tree, idAndParentIds) {// idAndParentIds用来保存所有节点的id,parentId
			// 对原有的数据结构进行遍历,拿出所有节点的id,parentId到一个一维数组中。
			tree.forEach(item => {
				let mid = {
					id: item.id,
					parentId: item.parentId,
				};
				idAndParentIds.push(mid);
				if (item.children) {
					this.getIdAndParent(item.children, idAndParentIds);
				}
			});
		},
getId(id, parentIds, idAndParent) {
			idAndParent.forEach(item => {
				if (item.id == id) {
					parentIds.push(id);
					if (item.parentId != -1) {
						this.getId(item.parentId, parentIds, idAndParent);
					}
				}
			});
		},
// 编辑时 数据回显
editShow() { // idAndParent保存 Tree所有节点的id和parentId
	let idAndParent=[];// idAndParent保存 Tree所有节点的id和parentId
        this.getIdAndParent(this.treeList,idAndParent);		
	let parentIds = []; // 用于保存选中节点的父节点及父节点的父节点
	this.getId(this.form.parentId, parentIds, idAndParent);

	this.parentId = parentIds.reverse(); //反转数组
},

我的级联框绑定的就是parentId ,进行编辑操作时,弹出表单时, 触发editShow(),方法, 从而触发了一系列别的方法,最后完成取到选中节点的所有的父节点,并将其赋值给parentId,完成回显。