一、要实现的交互有两种,分别需要两种方法实现(PS: 感觉应该还有别的实现方法,欢迎大佬们给出建议)
1、三级级联单选
思考:此时可以采用级联获取接口方式实现(每点一个节点,再调用下一级节点数据接口展示)官方需要以下格式,则在级联调用接口时拼成以下格式即可。
代码:
<el-cascader
ref="tree"
:value="optionsValue"
:options="options"
:props="{ checkStrictly: true }"
placeholder="区域 / 楼栋 / 设备号"
@visible-change="visibleChange"
@change="handleSearch"
@expand-change="expandChange"
collapse-tags
clearable>
</el-cascader>
let isHaveCityLs = false //是否有城市数据
let historyArrBuildingLs = [] //楼栋数据
let isHaveBuildingLs = false //是否有楼栋数据
let historyArrDeviceLs = [] //设备数据
let isHaveDeviceLs = false //是否有设备数据
export default {
data () {
return {
optionsValue: '',
options: []
}
},
methods: {
//第一级级联下拉点击事件
visibleChange(e) {
let _this = this;
if(e===true){
if(!isHaveCityLs){
let param = {}
//获取接口
_this.api.getCityLs(param).then(res => {
// console.log('res:', res)
if(res){
res.map((item, index)=>{
_this.options.push({
value: item.id,
label: item.name,
children: []
})
})
}
console.log('_this.options1:', _this.options)
isHaveCityLs = true; //防止重复push城市数据
})
}
}else{
// elDialogBuildingLs = false
// _this.options = []
// // 清空选中的节点
// _this.$refs.tree.$refs.panel.clearCheckedNodes();
// // 设置为空可以让节点不高亮显示
// _this.$refs.tree.$refs.panel.activePath = [];
}
},
//点节点事件
expandChange(e) {
let _this = this;
console.log(e)
//获取楼栋列表
if(e.length === 1 ){
for(let item in historyArrBuildingLs){
if(historyArrBuildingLs[item] === e[0]){
console.log('有')
isHaveBuildingLs = true; //已经添加过该节点
break;
}else{
isHaveBuildingLs = false;
}
}
if(!isHaveBuildingLs){
historyArrBuildingLs.push(e[0]);
}
console.log('historyArrBuildingLs:',historyArrBuildingLs)
if(!isHaveBuildingLs){
let param = {
city_list: [e[0]]
}
_this.api.getBuildingLs(param).then(res => {
if(res){
res.map((item, index)=>{
_this.options.map((itema, indexa)=>{
if(itema.value === e[0]){
itema.children.push({
value: item.id,
label: item.name,
children: []
})
}
})
})
}
})
}
}
//获取设备列表
if(e.length === 2 ){
for(let item in historyArrDeviceLs){
if(historyArrDeviceLs[item] === e[1]){
console.log('有')
isHaveDeviceLs = true; //已经添加过该节点
break;
}else{
isHaveDeviceLs = false;
}
}
if(!isHaveDeviceLs){
historyArrDeviceLs.push(e[1]);
}
if(!isHaveDeviceLs){
let param2 = {
building_list: [e[1]]
}
_this.api.getDeviceLs(param2).then(res => {
console.log('res:', res)
if(res && res.results){
res.results.map((item,index)=>{
_this.options.map((itema, indexa)=>{
if(itema.value === e[0]){
itema.children.map((itemb, indexb)=>{
if(itemb.value === e[1]){
console.log('itemb:', itemb)
itemb.children.push({
value: item.id,
label: item.name
})
}
})
}
})
})
}
})
}
}
console.log('_this.options2:', _this.options)
},
}
}
2、三级级联多选
思考:!!!经过试验,在采用如上单选的每级调接口再展示数据拼接(三级联动),会使options数据结构发生改变,从而使已选项发生错乱。!!!
解决方案就是,options直接赋值三级所有数据
PS: 这里不懂是不是只能直接用后端传来或自己拼成完整的数据结构才行了
代码:
<el-cascader
ref="tree"
:value="optionsValue"
:options="options"
:props="props"
placeholder="区域 / 楼栋 / 设备号"
@change="handleSearch"
collapse-tags
clearable>
</el-cascader>
//获取后端接口直接是以上options所用格式,直接赋值options即可
methods: {
getAreaInit() {
let _this = this;
let param = {}
_this.api.getTierData(param).then(res => {
console.log('getTierData:', res)
if(res){
_this.options = res;
}
})
}
}
二、总结
1、使用elemenui实现多级联动单选,可采用前端调每级接口再展示数据进行拼接(多级联调),但若想实现多级联动多选,则只能一开始就拼全所用数据。因为当你多选时,再次触发会使options构造发生改变,从而影响已选项。