乐趣区

关于vue.js:vue-elementui-中-elcascader的异步使用包括回显过滤

<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)
                }
            }
        }
    }
退出移动版