<template>
<!-- 异步数据字典联动控件封装 -->
<div
class="data-dict"
v-loading="!isFinishedGetOptions"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(255, 255, 255, 0)"
element-loading-custom-class="loading-cascader">
<el-cascader ref="dictCascaderRef"
v-model="_current"
:options="filterOptions || null"
:key="isFinishedGetOptions"
:props="dictTreeProps"
:disabled="disabled"
:filterable="filterable"
:clearable="clearable"
:multiple="multiple"
:size="size"
:before-filter="beforeFilter"
@blur="blurFn"
@change="changeFn"
></el-cascader>
</div>
</template>
<style lang="scss" scoped>
>>> .loading-cascader {
line-height: 32px;
.el-loading-spinner {
height: 32px;
line-height: 32px;
top: 0;
margin-top: 0;
text-align: right;
padding-right: 10px;
}
}
.data-dict {
position: relative;
.el-cascader,
.el-select {
display: block;
width: 100%;
}
}
</style>
import {arrayValueEquals} from '@/utils/util.js'
export default {components: {},
model: {
prop: 'value',
event: 'input'
},
props: {
value: { // 对应父组件 v -model 中的值
type: [Array],
default: () => null},
dictKey: { //
type: String,
required: true,
default: () => ''},
checkStrictly: {type: Boolean},
needReturnCheckedNodes: {type: Boolean,},
disabled: {type: Boolean},
multiple: {type: Boolean},
filterable: {type: Boolean},
clearable: {type: Boolean},
size: {type: String},
},
data () {
return {
filterKey: '',
filterOptions: [],
orginList: [],
currentVal: [],
isFinishedGetOptions: false,
dictTreeProps: null
}
},
computed: {
_current: {get () {return this.currentVal},
set (val) {
this.currentVal = val
this.$emit('input', val)
}
}
},
watch: {
value: {handler (newVal, oldVal) {if (newVal && Array.isArray(newVal) && newVal.length) {this.currentVal = newVal} else {this.currentVal = []
}
if (this.isFinishedGetOptions || arrayValueEquals(newVal, oldVal)) {return}
if (this.currentVal && this.currentVal.length) { // 如果以后有值,则获取数据用于回显
this.getAllTreeByCurrent()} else {this.getTreeInfo()
}
},
immediate: true
}
},
created () {
const ths = this
console.log('created')
ths.dictTreeProps = {
lazy: true,
children: 'children',
label: 'name',
value: 'key',
multiple: ths.multiple,
checkStrictly: ths.checkStrictly,
lazyLoad (node, resolve) {if (node.level === 0) {ths.getInitTree(resolve)
} else {ths.getChildrenInfo(node, resolve)
}
}
}
if (!ths.dictKey) {
ths.isFinishedGetOptions = true
return false
}
},
methods: {beforeFilter (val) {
const ths = this
ths.filterKey = val
const promise = new Promise((resolve,reject)=>{
const params = {
key: val,
source_uri: ths.dictKey
}
ths.$store.dispatch('xxxxxxx/getAllTreeByKeyword', params).then(res => {const tempList = Array.isArray(res.data) ? res.data : (res.data ? [res.data] : [])
if (tempList && tempList.length) {
ths.filterOptions = tempList
resolve(tempList)
} else {reject(new Error())
}
}).catch(res => {reject(new Error())
})
})
return promise
},
blurFn () {this.filterKey = ''},
// 值变动后回调
changeFn (value) {let nodes = []
if (this.needReturnCheckedNodes) {nodes = this.$refs.dictCascaderRef.getCheckedNodes() || []}
this.$emit('change', value, nodes)
},
// 获取子项列表
getChildrenInfo (current, resolve) {if (!current || !current.data || !current.data.id) {return false}
// 如果曾经有返回子节点数据
if (current.data.leaf || (resolve && current.data.children && current.data.children.length)) {resolve([])
} else {
const params = {node_id: current.data.id}
const ths = this
ths.$store.dispatch('dictdata/getTreeChildByKey', params).then(res => {let tempList = []
if (res.data && res.data.length && res.data[0].children && res.data[0].children.length) {tempList = this.removeEmptyFn(res.data[0].children || [])
}
if (resolve) {resolve(tempList)
}
}).catch(res => {resolve([])
})
}
},
// 移除子列表为空
removeEmptyFn (list = []) {
const ths = this
const tempList = list
tempList.forEach(item => {if (!item.children || !item.children.length) {delete item.children} else {item.children = ths.removeEmptyFn(item.children)
}
})
return tempList
},
/**
* 依据以后值获取树(用于回显
* 例如 [[11,111,1111], [13,131]] 则从后盾返回第一级别所有数据【11;12;13...】,【11】children 的所有数据,【111】children 的所有数据,【13】children 的所有数据,)*/
getAllTreeByCurrent () {
const ths = this
const params = {path: ths.currentVal || [],
source_uri: ths.dictKey
}
ths.isFinishedGetOptions = false
ths.$store.dispatch('xxxx/getAllTreeByCurrent', params).then(res => {const tempList = Array.isArray(res.data) ? res.data : (res.data ? [res.data] : [])
if (tempList && tempList.length) {
ths.isFinishedGetOptions = true
ths.orginList = tempList
} else {ths.getTreeInfo()
}
}).catch(res => {ths.isFinishedGetOptions = true})
},
// 初始化信息
getTreeInfo () {
const ths = this
const params = {
key: ths.dictKey,
view_type: 'tree'
}
ths.isFinishedGetOptions = false
ths.$store.dispatch('xxx/getTreeInfo', params).then(res => {const tempList = res.data || []
ths.orginList = tempList
}).catch(res => {}).finally(() => {ths.isFinishedGetOptions = true})
},
// 初始化第一级信息
getInitTree (resolve) {
const ths = this
if (ths.isFinishedGetOptions) {if (resolve) {resolve(ths.orginList)
}
} else {setTimeout(() => {ths.getInitTree(resolve)
}, 300)
}
}
}
}