今日,在vue項目中使用餓了麼的Cascader級聯選擇器時,遇到了一個問題,情景時這樣的, 數據是從後臺拿到的,前端要做出的效果是當滿足某些條件時,某些選項禁止選中。花了很長時間解決這個問題,於是寫這篇文章記錄解決方案。
如上圖所示,假如 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,完成回顯。