一、使用方法及源吗
使用方法
// postInfo为每层下钻岗位的id selectedName为XXX岗位名称,也就是最后需要显示的岗位信息 url为获取岗位信息的url
// postInfo: [111,222,333], selectedName: '皮草运营商', url: "xxx.findxxx"
<origanizeCascader v-model="postInfo" :selected-name.sync="selectedName" url="xxx.findxxx"/>
源代码origanize-cascader.vue
<template>
<el-cascader
v-model="checkedValue"
:options="options"
:props="config"
:show-all-levels="false"
ref="cascader"
popper-class="sc-cascader-popper cascader-popper"
/>
</template>
<script>
export default {
props: {
value: {
type: Array,
default: () => []
},
selectedName: {
type: String,
default: ''
},
url: {
type: String,
default: 'xxx'
}
},
data() {
return {
checkedValue: [],
options: [],
config: {
label: 'dimName',
value: 'pId',
leaf: 'hasChild',
checkStrictly: true,
lazy: true,
lazyLoad: this.lazyLoad
},
inited: false,
hadIds: []
};
},
watch: {
'$store.state.user': {
handler(newVal) {
if (!newVal || !newVal.postList || !newVal.postList.pId) {
return;
}
this.initOptions(newVal.postList.pId).then(() => {
this.checkedHad(this.options);
});
}
},
checkedValue: {
deep: true,
handler(newVal) {
if (
newVal.length === this.value.length
&& this.value.every(v => newVal.includes(+v))
) {
return;
}
this.$emit('input', newVal);
}
},
value: {
deep: true,
handler(newVal) {
if (!this.inited) {
return;
}
if (
newVal.length === this.checkedValue.length
&& newVal.every(v => this.checkedValue.includes(+v))
) {
return;
}
this.setCheckedValue();
}
},
selectedName(newVal) {
if (newVal) {
this.$refs.cascader.inputValue = newVal;
}
}
},
mounted() {
this.$refs.cascader.$refs.panel.$watch('menus', {
handler(newVal) {
const len = newVal.length;
if (!newVal[len - 1].length) {
this.menus.splice(len - 1, 1);
}
}
});
this.$refs.cascader.$watch('inputValue', {
immediate: true,
handler: newVal => {
if (newVal && newVal !== this.selectedName) {
this.$emit('update:selectedName', newVal);
}
}
})
},
methods: {
lazyLoad(node, resolve) {
if (node.isLeaf || node.root || this.hadIds.includes(node.value)) {
return resolve();
}
this.getChildren(node.value)
.then(res => {
resolve(res);
});
},
getChildren(pId) {
return this.$axios
.post(this.url, {
pId
}).then(res => {
if (res.data === '') {
this.$alert('无权限,请联系管理员');
this.$trigger('setLoading', false);
return;
}
return res.data.dataList;
}).catch(error => {
this.$alert(error.msg || "获取下辖岗位失败,请稍后重试", "错误提示");
});
},
initOptions(pId) {
return this.getChildren(pId)
.then(res => {
if (res[0].pId === pId) {
this.options = res;
}
else {
const {pName, pId} = this.$store.state.user.postList;
this.options = [{
dimName: pName,
pId,
hasChild: false,
children: res
}];
}
})
.finally(() => {
this.inited = true;
this.setCheckedValue();
})
},
checkedHad(arr) {
arr.forEach(v => {
if (v.children && v.children.length) {
this.hadIds.push(+v.pId);
this.checkedHad(v.children);
}
})
},
setCheckedValue() {
if (this.value.length < 3) {
this.checkedValue = this.value.map(v => +v);
}
else {
const arr = this.value.slice(1, this.value.length - 1);
Promise
.all(arr.map(v => this.getChildren(v)))
.then(res => {
this.handlerOption(res);
this.checkedValue = this.value.map(v => +v);
});
}
},
handlerOption(res) {
const len = res.length;
const needSetChildrenOption = this.options[0].children.find(v => +v.pId === +this.value[1]);
for(let i = 0; i < len - 1; i++) {
const item = res[i].find(v => +v.pId === +this.value[i + 2]);
item.children = res[i + 1];
}
this.$set(needSetChildrenOption, 'children', res[0]);
this.checkedHad(this.options);
this.hadIds = [...new Set(this.hadIds)];
}
}
};
</script>
<style lang="less">
.sc-cascader-popper {
max-width: 70%;
min-width: 100px;
overflow-x: auto;
.el-cascader-panel {
.el-cascader-menu__wrap {
height: 100% !important;
}
.el-scrollbar__wrap {
overflow-y: auto;
overflow-x: hidden;
margin-bottom: 0 !important;
margin-right: 0 !important;
}
.el-cascader-menu {
flex-shrink: 0;
}
}
}
</style>
二、效果展示
默认
展开:
三、源码解析
流程: