element-ui封装下拉选择组件

903 阅读1分钟

效果图

D7BEAA23-AE9F-41a6-B86D-AE9710B1B2BA.png

代码 用的是vue3写法,喜欢用vue2的同学可以自行修改下。

   父组件
     <select-tree :treeData="treeData" :labelId="ruleForm.parentId" 
                     @selectTreeVal="selectTreeFather"></select-tree>
                     
    // 接收选中的数据                 
    const selectTreeFather =(params)=> {
      console.log('父组件获取树数据', params)
      diaData.ruleForm.parentRealVal = params
    }                
                     
                     
    子组件
    <template>
    <div>
        <el-select v-model="label"
              ref="selectRef"
              multiple
              @remove-tag="removeTag"
              placeholder="请选择">
            <template #empty>
                <div class="selectClose">
                    <i class="el-icon-close" @click="closeSelect"></i>
                </div>
                <div class="selectTree">
                  <el-tree
                    :data="treeData"
                    :props="propsDefault"
                    show-checkbox
                    check-strictly
                    :node-key="nodeKey"
                    check-on-click-node
                    default-expand-all
                    ref="treeListDept"
                    :expand-on-click-node="false"
                    @check-change="(data, data2) => checkChangeTree(data, data2)">
                  </el-tree>
                </div>
            </template>
        </el-select>
    </div>
</template>

<script>
import { reactive, toRefs, ref, onMounted, watch, nextTick } from 'vue'

export default {
    props: {
        // 编辑时获取真实值映射
        labelId: {
            type: Array,
            default: () => []
        },
        // id映射值
        idVal: {
            type: String,
            default: 'id'
        },
        // label映射值
        labelVal: {
            type: String,
            default: 'label'
        },
        // 树形列表
        treeData: {
            type: Array,
            default: () => []
        },
        // 单选0 多选1
        isSingle: {
            type: String,
            default: '0'
        }
    },
    setup(props, ctx) {
        const selectRef = ref(null)
        const treeListDept = ref(null)
        const diaData = reactive({
            propsDefault: {
                label: props.labelVal
            },
            nodeKey: props.idVal,
            label: [],    // 展示名字
            labelRealVal: [],    // 全部数据-id、label
            showIndex: true
        })
        onMounted(() => {
        })
        watch(()=> props.labelId, (val)=> {
            console.log(props.labelId, val, 'ssssss')
            nextTick(() => {
                treeListDept.value.setCheckedKeys(val)
            })
        },
        {
            deep: true,
            immediate: true
        })
        // 父级树监听选择值
        let checkChangeTree = (data, data2) => {
            if(props.isSingle == '1') {
                // 多选
                if(data2) {
                    diaData.label.push( data[`${props.labelVal}`] )
                    diaData.labelRealVal.push( {id: data[`${props.idVal}`], label: data[`${props.labelVal}`]} )
                }
                else {
                    let index = diaData.labelRealVal.findIndex((item) => {
                        return item.id == data[`${props.idVal}`]
                    })
                    if(diaData.showIndex) {
                        diaData.label.splice(index, 1)
                        diaData.labelRealVal.splice(index, 1)
                    }
                    diaData.showIndex = true
                }
            } else {
                // 单选
                if(data2) {
                    treeListDept.value.setCheckedKeys([ data[`${props.idVal}`] ])
                    diaData.label = [ data[`${props.labelVal}`] ]
                    diaData.labelRealVal = [{ id: data[`${props.idVal}`], label: data[`${props.labelVal}`] }]
                } else {
                    diaData.labelRealVal.forEach((item) => {
                        if(item.id == data.id) {
                            diaData.label = []
                            diaData.labelRealVal = []
                        }
                    })
                }
            } 
            checkVal()
        }
        // 标签删除
        let removeTag = (tag) => {
            if(props.isSingle == '1') {
                // 多选
                diaData.labelRealVal.findIndex((item, index) => { 
                    console.log(item)
                    if(item.label == tag) {
                        treeListDept.value.setChecked(item.id, false)
                        diaData.labelRealVal.splice(index, 1)
                        diaData.showIndex = false
                    }
                    return item.label == tag
                })
            } else { 
                // 单选
                treeListDept.value.setCheckedKeys([])
            }
        }
        // 将选中值,返回给父组件
        const checkVal =()=> {
            ctx.emit('selectTreeVal', diaData.labelRealVal)
        }
        const closeSelect=()=> {
            selectRef.value.blur()
        }
        return {
            ...toRefs(diaData),
            treeListDept,
            checkChangeTree,
            removeTag,
            checkVal,
            selectRef,
            closeSelect
        }
    },
}
</script>
<style lang="scss" scoped>
    .selectClose {
        text-align: right;
        padding: 15px 15px 0px 15px;
        font-size: 16px;
        i {
             cursor: pointer;
        }
    }
</style>