需求说明:同一个页面新增时,默认只显示一个选择器(选择器是循环出来的),可以新增、删除、编辑;编辑的时候根据后端返回数据循环显示选择器列表,可新增、删除、编辑;
数据说明:后端默认只返回一级节点的数据,二级数据在点击对应一级节点的时候查询,并设置到一级节点的 children 字段中,我这里只有两级,三级节点同理;
传给后端:最终选择的的节点数据为二级节点的 id 组成的数组,如:[10, 13, 15];
test.vue template:
1 <!-- test.vue -->
2 <template> 3 <div v-for="(item, index) in cascaderList" :key="item.id" style="margin-top: 0;"> 4 <el-cascader 5 :ref="'cascader' + index" 6 v-model="item.cascaderValue" 7 :show-all-levels="true" 8 :options="cascaderOptions" 9 :placeholder="item.cascaderPlaceholder" 10 @change="(val) => cascaderChange(val, index)" 11 @expand-change="(val) => cascaderItemChange(val)" 12 @visible-change="(val) => cascaderVisibleChange(val, item)" 13 ></el-cascader> 14 <el-button type="primary" icon="el-icon-plus" size="small" circle @click="cascaderAdd" v-if="index == 0"></el-button> 15 <el-button type="danger" icon="el-icon-delete" size="small" circle @click="cascaderDel(index)" v-else></el-button> 16 </div> 17 </template>
test.vue script:
1 <script> 2 let id = 100000 3 let resData = { 4 data: { 5 "knowledgeEntityList": [ 6 { 7 "knowledgeId": 65, 8 "knowledgeName": "xier sort", 9 "parentId": 61, 10 "parentName": "排序" 11 }, 12 { 13 "knowledgeId": 72, 14 "knowledgeName": "身份证格式", 15 "parentId": 70, 16 "parentName": "正则表达式" 17 }, 18 { 19 "knowledgeId": 75, 20 "knowledgeName": "链表", 21 "parentId": 74, 22 "parentName": "数据库" 23 } 24 ] 25 } 26 error_no: "0" 27 }
28 let parentData = { 29 "data": [ 30 { 31 "childrenCount": 4, 32 "id": 61, 33 "knowledgeName": "排序", 34 "orderIndex": 0, 35 "parentId": 0, 36 "status": 1 37 }, 38 { 39 "childrenCount": 3, 40 "id": 62, 41 "knowledgeName": "集合", 42 "orderIndex": 1, 43 "parentId": 0, 44 "status": 1 45 }, 46 { 47 "childrenCount": 1, 48 "id": 63, 49 "knowledgeName": "字符串", 50 "orderIndex": 2, 51 "parentId": 0, 52 "status": 1 53 }, 54 { 55 "childrenCount": 4, 56 "id": 70, 57 "knowledgeName": "正则表达式", 58 "orderIndex": 3, 59 "parentId": 0, 60 "status": 1 61 }, 62 { 63 "childrenCount": 1, 64 "id": 74, 65 "knowledgeName": "数据库", 66 "orderIndex": 4, 67 "parentId": 0, 68 "status": 1 69 }, 70 { 71 "childrenCount": 1, 72 "id": 78, 73 "knowledgeName": "数组", 74 "orderIndex": 5, 75 "parentId": 0, 76 "status": 1 77 } 78 ], 79 "error_no": "0" 80 } // 一级节点数据
let childData = [
{
"childrenCount": 0,
"id": 71,
"knowledgeName": "邮箱格式",
"orderIndex": 0,
"parentId": 70,
"status": 1
},
{
"childrenCount": 0,
"id": 72,
"knowledgeName": "身份证格式",
"orderIndex": 1,
"parentId": 70,
"status": 1
},
{
"childrenCount": 0,
"id": 73,
"knowledgeName": "密码格式",
"orderIndex": 2,
"parentId": 70,
"status": 1
}
]
81 82 export default { 83 name: 'Test', 84 85 data() { 86 cascaderPlaceholder: '请选择知识点', 87 cascaderList: [ 88 { 89 id: id - 1 90 } 91 ], // 选择器列表 92 cascaderOptions: [], // 选择器展示数据 93 knowledgeId: [], // 选择的二级节点数据,传递给后端 94 problemId: null 95 }, 96 97 async mounted() { 98 this.problemId = this.$route.query.id || 10 // 此处的 10 用于测试 99 if (this.problemId) { 100 this.queryProblem(this.problemId) 101 } 102 // 查询一级节点数据 103 let nodes = await this.queryKnowledgeFn(0) 104 this.cascaderOptions = nodes 105 }, 106 107 methods: { 108 // 查询详情 109 async queryProblem(problemId) { 110 // 发起请求 111 setTimeout(() => { 112 let r = resData 113 let data = r.data 114 if (r.error_no == '0') { 115 // 节点回显 116 let knowledgeEntityList = data.knowledgeEntityList || [] 117 if (knowledgeEntityList.length > 0) { 118 let _cascaderList = [] 119 knowledgeEntityList.forEach((item) => { 120 this.knowledgeId.push(item.knowledgeId) 121 _cascaderList.push({ 122 id: item.knowledgeId, 123 parentId: item.parentId, 124 cascaderValue: [item.parentId, item.knowledgeId], 125 cascaderPlaceholder: `${item.parentName} / ${item.knowledgeName}` 126 }) 127 }) 128 this.cascaderList = _cascaderList 129 } else { 130 this.cascaderList = [ 131 { 132 id: id - 1 133 } 134 ] 135 } 136 } 137 }, 1000) 138 }, 139 140 // 查询节点数据 141 async queryKnowledgeFn(parentId) { 142 let knowledgeId = this.knowledgeId 143 // 发起请 144 setTimeout(() => { 145 const res = parentData 146 if (res.error_no == '0') { 147 let _data = res.data || [] 148 _data.forEach((item) => { 149 item.label = item.knowledgeName 150 item.value = item.id 151 // children 代表为叶子结点,会显示展开箭头 152 if (item.childrenCount > 0) { 153 item.children = [] 154 } 155 // 通过 disabled 设置选项禁用,根据已选择的二级知识点来设置禁用 156 item.disabled = false 157 knowledgeId.forEach((pItem) => { 158 if (pItem == item.id) { 159 item.disabled = true 160 } 161 }) 162 }) 163 return _data 164 } 165 }, 1000) 166 }, 167 168 // 新增节点 169 cascaderAdd() { 170 this.cascaderList.push({ 171 id: id++ 172 }) 173 }, 174 175 // 删除节点 176 cascaderDel(index) { 177 this.cascaderList.splice(index, 1) 178 this.knowledgeId.splice(index, 1) 179 }, 180 181 // 节点选择 182 cascaderChange(valArr, index) { 183 let child = valArr[valArr.length - 1] 184 this.$set(this.knowledgeId, index, child) 185 }, 186 187 // 父节点点击 188 cascaderItemChange(val) { 189 this.setParentData(val[0] || 10) 190 }, 191 192 // 选择器展示、隐藏 val:true显示,false隐藏 193 cascaderVisibleChange(val, item) { 194 if (val && item.cascaderValue) { 195 this.setParentData(item.cascaderValue[0]) 196 } 197 }, 198 199 // 查询子节点数据,更新 cascaderOptions 数据,将子节点数据插入对应父节点的 children 中 200 async setParentData(parentId) { 201 let _cascaderOptions = this.cascaderOptions 202 let _index = _cascaderOptions.findIndex((itm) => itm.id == parentId) 203 // let nodes = await this.queryKnowledgeFn(parentId)
// 发请求 拿到子节点数据,此处为模拟数据
let nodes = childData 204 _cascaderOptions[_index].children = nodes 205 } 206 } 207 } 208 </script>
标签:el,ElementUI,选择器,item,let,parentId,knowledgeName,节点,id From: https://www.cnblogs.com/rzsyztd/p/16738082.html