1
<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)
                }
            }
        }
    }

toutouping
190 声望12 粉丝

每天进步一点点,遇见更好的自己