vue+element UI之el-select和el-tree实现单选/复选/搜索组件封装

  最近在写代码的时候遇到一个需求,就是需要试用下拉菜单完成二级菜单选择、甚至有三级的菜单选择:
  UI提出此功能需要有以下三个要点:

  • 在不同的情况下要实现单选或者多选
  • 选择的内容要回调在输入框内
  • 既可以下拉选择又可以搜索选择
      基于此,我开始设计了这个组件。话不多说 上效果图。
  • 多选效果图
    vue+element UI之el-select和el-tree实现单选/复选/搜索组件封装_第1张图片
  • 单选效果图
    vue+element UI之el-select和el-tree实现单选/复选/搜索组件封装_第2张图片
     &emsp话不多说上代码:

父组件

<template>
    <div class="demo">
        <elTree :list="options" :defaultProps="defaultProps" @getdetail="getdetail" :selectType="selectType"> </elTree>
    </div>
</template>

<script>
import elTree from './elTree.vue'
export default {
    components: {
        elTree,
    },
    data() {
        return {
            options: [
                {
                    id: 1,
                    label: '一级 2',
                    value: '一级2',
                    disabled: false,
                    children: [
                        {
                            id: 3,
                            label: '二级 2-1',
                            value: '二级2-1',
                            disabled: false,
                            children: [
                                {
                                    id: 4,
                                    label: '三级 3-1-1',
                                    value: '三级3-1-1',
                                    disabled: false,
                                },
                                {
                                    id: 5,
                                    label: '三级 3-1-2',
                                    value: '三级3-1-2',
                                    disabled: false,
                                },
                            ],
                        },
                        {
                            id: 2,
                            label: '二级 2-2',
                            value: '二级2-2',
                            disabled: true,
                            children: [
                                {
                                    id: 6,
                                    label: '三级 3-2-1',
                                    value: '三级3-2-1',
                                    disabled: false,
                                },
                                {
                                    id: 7,
                                    label: '三级 3-2-2',
                                    value: '三级3-2-2',
                                    disabled: false,
                                },
                            ],
                        },
                    ],
                },
            ],
            // 数据格式化====必填
            defaultProps: {
                children: 'children',
                label: 'label',
                value: 'value',
            },
            //单选或者复选
            selectType: 'single',//multiple为多选
        }
    },
    methods: {
        //获取勾选数据
        getdetail(val) {
            console.log(val, '222222222')
        },
    },

}
</script>

子组件代码

<template>
    <div class="app-container caseManagementIndex scrollcontainer scrollcontainer_auto" ref="caseManagementIndex" v-if="list.length > 0">
        <el-select v-model="value" filterable :multiple="multiple" placeholder="请选择" :popper-append-to-body="false" :filter-method="assetsTypeFilter">
            <el-option :value="selectTree" class="setstyle" disabled>
                <el-tree
                    :data="list"
                    :props="defaultProps"
                    ref="tree"
                    node-key="id"
                    show-checkbox
                    check-strictly
                    :expand-on-click-node="false"
                    check-on-click-node
                    @check-change="checkChangeClick"
                    :filter-node-method="filterNode"
                ></el-tree>
            </el-option>
        </el-select>
    </div>
</template>

<script>
export default {
    name: 'caseManagementIndex',
    // import引入的组件需要注入到对象中才能使用PopupTreeInput
    components: {},
    props: {
        list: {
            type: Array,
            default: () => [],
        },
        defaultProps: {
            type: Object,
            default: {
                //children: 'children',
                //label: 'label',
            },
        },
        selectType: {
            type: String,
            default: 'multiple',
        },
    },
    data() {
        // 这里存放数据
        return {
            value: [],
            selectTree: [],
            multiple: true,
        }
    },
    // 监听属性 类似于data概念
    computed: {},
    // 监控data中的数据变化
    watch: {},
    // 生命周期 - 创建完成(可以访问当前this实例)
    created() {},
    // 生命周期 - 挂载完成(可以访问DOM元素)
    mounted() {
        console.log('flatten(fromData)', this.flatten(this.list))
        this.selectTree = this.flatten(this.list)
    },
    // 方法集合
    methods: {
        flatten(arr) {
            return [].concat(
                ...arr.map((item) => {
                    if (item.children) {
                        let arr = [].concat(item, ...this.flatten(item.children))
                        delete item.children
                        return arr
                    }
                    return [].concat(item)
                }),
            )
        },
        assetsTypeFilter(val) {
            // 下拉框调用tree树筛选
            //console.log(this, val)
            this.$refs.tree.filter(val)
        },
        checkChangeClick(data, self, child) {
            console.log(data, self, child, this.selectType)
            if (this.selectType == 'multiple') {
                let datalist = this.$refs.tree.getCheckedNodes()
                //console.log('datalist', datalist)
                this.value = []
                datalist.forEach((item) => {
                    this.value.push(item.label)
                })
                let values = datalist.map((item) => {
                    return item.value
                })
                this.$emit('getdetail', datalist)
            } else {
                if (self) {
                    this.$refs.tree.setCheckedNodes([data])
                    this.multiple = false
                    this.value = data.label
                    this.$emit('getdetail', data)
                }
            }
        },
        filterNode(value, data) {
            if (!value) return true
            return data.label.indexOf(value) !== -1
        },
    },
}
</script>
<style lang="scss">
.setstyle {
    min-height: 200px;
    padding: 0 !important;
    margin: 0;
    overflow: auto;
    cursor: default !important;
}
</style>
<style lang="scss" scoped></style>

  以上el-select和el-tree实现单选/复选/搜索组件封装就好啦。

实现思路:

1、可搜索

利用属性:filterable +方法 filter-method实现

2、复选和单选控制

利用**:multiple="multiple"selectType进行判断,不同的情况下,勾选的结果是单选还是多选,走不通的业务逻辑

  如果你觉得本文写的不错的话,记得收藏、关注和点赞哟,

你可能感兴趣的:(vue项目,vue.js,ui,javascript,elementui)