Vue 可输入可下拉组件的封装

由于业务需要,需要一个可输入也可下拉的组件,看了iview没有现成的组件用,就自己封装了个小组件~~

组件input-select.vue代码:

<template>
    <div class="input-container">
        <!-- 显示的输入框,用v-model绑定数据,并且绑定focus事件 -->
        <Input class="input-number" v-model="inputData" @on-focus="_showInputNumber" />
        <!--  -->
        <div class="input-dropdown-wrap">
            <Dropdown trigger="custom" :visible="visibNormal" class="input-dropdown">
                <Dropdown-menu slot="list">
                    <div class="dropdown-list">
                        <Row class="item" v-fot="item of arrayList" :value="item.code" :key="item.code" @click.native="_inputNumChange(item.code)">{{item.text}}</Row>
                    </div>
                </Dropdown-menu>
            </Dropdown>
        </div>
    </div>
</template>

<script>
/**
 * 输入下拉框
 * @author  mino
 * @version 1.0.0
 * @description 可输入,也可展开下拉框进行选择
 */
export default {
    data() {
        return {
            inputData: '1',    //输入框的默认值
            visibNormal: false    //下拉显示控制
        }
    },
    props: {
        arrayList: {    //下拉列表的数据
            type: Array,
            default: []
        }
    },
    watch: {
        inputData(newVal) {
            this.$emit('getInputNum', newVal);
        }
    },
    methods: {
        //展示下拉选项
        _showInputNumber(e) {
            let _this = this;
            if(this.visibNormal) return;
            
            this.visibNormal = true;
            //给输入框元素加入阻止冒泡事件
            e.target.addEventListener('click', (e) => {
                e.stopPropagation();
            });
            document.addEventListener('click', _this._hideNormal);
        },
        //下拉框列表的点击事件
        _inputNumChange(data) {
            this.$emit('getInputNum', data);
        },
        //隐藏下拉框
        _hideNormal() {
            let curTarget = event.target;
            if(curTarget.nodeName === 'SPAN' && curTarget.classList.contains('switch)) {
                return;
            }
            
            this.visibNormal = false;
            document.removeEventListener('click', this._hideNormal);
        }
    }
}
</script>

<style scoped lang="less">
    .input-container {
        /deep/ .input-dropdown-wrap {
            height: 0 !important;
            overflow: hidden;
        }
        .dropdown-list {
            height: 1.3rem;
            overflow: auto;
            border-bottom: .01rem solid #E4E4E4;
            .item {
                line-height: .25rem;
                padding-left: .15rem;
                &:hover {
                    background: grey;
                }
            }
        }
        .input-number {
             2.2rem;
        }
        .input-dropdown {
             2.2rem;
            /deep/ .ivu-select-dropdown {
                margin-top: -.2rem;
            }
        }
    }
</style>

调用该组件的组件index.vue代码块为:

<template>
    <div class="main-container">
        <inputSelect :arrayList="_arrayList" @getInputNum="_getInputNum" />
    </div>
</template>

<script>
/**
 * 输入下拉组件引用主入口
 * @author  mino
 * @version 1.0.0
 * @description 引用输入下拉组件
 */
import inputSelect from './input-select';
export default {
    data() {
        return {
            _arrayList: [
                {
                    code: '1',
                    text: '111'
                },
                {
                    code: '3',
                    text: '333'
                },
                {
                    code: '5',
                    text: '555'
                }
            ],
            inputSelectData: ''    //接收子组件的值
        }
    },
    components: {
        inputSelect
    },
    methods: {
        //获取子组件的值
        _getInputNum(data) {
            console.log('this is data of input-select: ', data);
            this.inputSelectData = data;
        }
    }
}
</script>
原文地址:https://www.cnblogs.com/minozMin/p/10254231.html