el-select and el-tree of vue+element UI implement single selection/check/search component encapsulation

  Recently, when writing code, I encountered a requirement, that is, to use the drop-down menu to complete the second-level menu selection, and even the third-level menu selection:
  The UI proposes that this function needs the following three points:

  • To achieve single or multiple selection in different situations
  • The selected content should be called back in the input box
  • Both drop-down selection and search selection
      Based on this, I started designing this component. Not much to say about the renderings.
  • Multi-choice renderings
    insert image description here
  • Single selection effect diagram
    insert image description here
     & emsp not much to say about the code:

parent component

<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>

subcomponent code

<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>

  The above el-select and el-tree realize the encapsulation of single-selection/multi-selection/search components.

Implementation ideas:

1. Searchable

Use attribute: filterable + method filter-method implementation

2. Check and radio control

Use **:multiple="multiple" and selectType to judge. Under different circumstances, whether the result of the check is single selection or multiple selection, the business logic that does not work

  If you think this article is well written, remember to bookmark, follow and like it,

おすすめ

転載: blog.csdn.net/m0_62209297/article/details/127981434