uniapp 下拉选择框

下拉框组件:

<template>
    <view class="item-info" :class="border ? '' : 'no-border'">
        <view class="title" :style="labelStyle">
            {{title}}
        </view>
        <view class="info-right">
            <view class="txt" @click="clickHandle">{{inputVal}}</view>
            <view class="img-wrap" @click="clickHandle">
                <image src="../static/arrow_down.png"></image>
            </view>
        </view>
        <view class="list-wrap" v-if="showSelector">
            <view class="list-arrow"></view>
            <scroll-view scroll-y="true" class="list">
                <view class="empty-txt" v-if="selectList.length === 0">
                    {{emptyTips}}
                </view>
                <view class="list-item" 
                    v-for="(item,index) in selectList" :key="index" 
                    :class="{'list-item1':selectIndex==index?true:false}"
                    @click="onSelectorClick(index)">
                    <text>{{item}}</text>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
    /**
     * Combox 组合输入框
     * @property {String} title 左侧文字
     * @property {String} titleWidth 左侧内容宽度
     * @property {Array} selectList 选项列表
     * @property {String} selectIndex 筛选列表当前显示的索引
     * @property {String} emptyTips 筛选列表为空时显示的文字
     */
    export default {
        name: 'uniCombox',
        props: {
            border: {
                type: Boolean,
                default: true
            },
            title: {
                type: String,
                default: ''
            },
            titleWidth: {
                type: String,
                default: 'auto'
            },
            selectList: {
                type: Array,
                default () {
                    return []
                }
            },
            selectIndex:{
                type:Number,
                default:99
            },
            emptyTips: {
                type: String,
                default: '暂无数据'
            },
        },
        data() {
            return {
                showSelector: false,
                inputVal: '',
            }
        },
        computed: {
            labelStyle() {
                if (this.titleWidth === 'auto') {
                    return ""
                }
                return `width: ${this.titleWidth}`
            },
        },
        methods: {
            toggleSelector() {
                this.showSelector = !this.showSelector
            },
            onSelectorClick(index) {
                this.inputVal = this.selectList[index];
                this.showSelector = false;
                this.$emit("iptHandle",{iptVal:this.inputVal,curIndex:index});
            },
            clickHandle() {
                this.showSelector = !this.showSelector;
            }
        }
    }
</script>

<style lang="scss" scoped>
    .item-info {
        width: 694rpx;
        height:72rpx;
        padding:0 28rpx;
        font-size: 28rpx;
        border-bottom: 1px solid #DCDFE6;
        position: relative;
        display: flex;
        flex-direction: row;
        align-items: center;
        .title {
            font-size: 32rpx;
            font-weight: bold;
            margin-right: 20rpx;
            color: #333;
        }
        .info-right {
            position: relative;
            display: flex;
            flex: 1;
            flex-direction: row;
            align-items: center;
            .txt {
                flex: 1;
                font-size: 32rpx;
            }
            .img-wrap{
                width:50rpx;
                height:72rpx;
                display: flex;
                justify-content: center;
                align-items: center;
                image{
                    width: 28rpx;
                    height:20rpx;
                }
            }
        }
    }
    .list-wrap {
        box-sizing: border-box;
        position: absolute;
        top: calc(100% + 12px);
        left: 0;
        width: 100%;
        background-color: #FFFFFF;
        border: 1px solid #EBEEF5;
        border-radius: 12rpx;
        box-shadow: 0 4rpx 24rpx 0 rgba(0, 0, 0, 0.1);
        z-index: 99;
        padding: 8rpx 0;
        .list-arrow,
        .list-arrow::after {
            position: absolute;
            display: block;
            width: 0;
            height: 0;
            border-color: transparent;
            border-style: solid;
            border-width: 12rpx;
        }
        
        .list-arrow {
            filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
            top: -12rpx;
            left: 10%;
            margin-right: 6rpx;
            border-top-width: 0;
            border-bottom-color: #EBEEF5;
        }
        .list-arrow::after {
            content: "";
            top: 1px;
            margin-left: -12rpx;
            border-top-width: 0;
            border-bottom-color: #fff;
        }
        .list {
            max-height: 400rpx;
        }
        
        .empty-txt,
        .list-item {
            display: flex;
            cursor: pointer;
            line-height: 72rpx;
            font-size: 32rpx;
            text-align: center;
            padding: 0px 20rpx;
        }
        .list-item1{
            color:#007AFF;
        }
        .empty-txt:last-child,
        .list-item:last-child {
            border-bottom: none;
        }
    }
    .no-border {
        border: none;
    }
</style>

引入并使用:

<template>
    <view class="content">
        <uni-combox title="课程" :titleWidth="200" :selectIndex="curIndex" :selectList="gradeList" @iptHandle="getTxt"></uni-combox>
    </view>
</template>

<script>
    import uniCombox from "@/components/uni-combox.vue"
    export default {
        data() {
            return {
                gradeList: [
                    "语文",
                    "数学",
                ],
                iptVal: "",
                curIndex:0,
            };
        },
        components: {
            "uni-combox": uniCombox,
        },
        onLoad(options) {

        },
        methods: {
            getTxt(v) {
                this.iptVal = v.iptVal;
                this.curIndex = v.curIndex;
            },
        }
    }
    
</script>

<style lang="scss">
    page {
        background: #f4f4f4;
    }
</style>

 

posted @ 2022-09-26 12:08  云里知音  阅读(1835)  评论(0)    收藏  举报