<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)
}
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。