本文使用vue2.0+elementui 制作一个上门取件时间组件,类似顺丰,样式如下:

大概功能:点击期望上门时间,下面出现一个弹框可以选择时间:

首先我们定义一些需要的数据:

  data() {
        return {
            isDropdown: false,
            dayList: [],
            listArray: [
                "08:00~09:00",
                "09:00~10:00",
                "10:00~11:00",
                "11:00~12:00",
                "12:00~13:00",
                "13:00~14:00",
                "14:00~15:00",
                "15:00~16:00",
                "16:00~17:00",
                "17:00~18:00",
                "18:00~19:00",
                "19:00~19:30",
            ],
            timeToList: {
            },
            timeValue: "今天",
            clickValue: "一小时内",
            clickDay: "今天",
            time: "",
        }
    },

接着我们画一个期望上门时间的长框,点击可以出现弹窗,点击外部弹窗消失,这中间我们使用了import Clickoutside from 'element-ui/src/utils/clickoutside' 这一组件,来帮助我们达到这个目的

<template>
    <div class="time-picker" @click="openDown" v-clickoutside="clickoutside">
        <div class="content-first">
            <div class="redSpan">*</div>
            <div>期望上门时间</div>
        </div>
        <div class="content-first">
            <div>
                {{ time }}
            </div>
            <i class="el-icon-s-order"></i>
        </div>
</template>

接下来画一个弹出页面,弹出页面顶部是一个tab组件,这里通过daylist循环获得

   <div class="time">
                <div v-for="item in dayList" class="item" :class="timeValue == item.lable ? 'active' : ''"
                    @click="dayChange(item)">
                    <div>{{ item.lable }}</div>
                    <div>{{ item.ymd }}</div>
                </div>
            </div>

tab组件中的内容,是下单时间的按钮集合,通过timeToList 这个结构体 ,先获取数组再循环生成

           <div class="timeList">
                <div v-for="item  in  timeToList[timeValue]" @click="timeChange(item)" class="timeBox"
                    :class="clickDay == item.day && clickValue == item.lable ? 'active' : ''">
                    {{ item.lable }}
                </div>
            </div>

页面写好了我们开始写逻辑代码,先需要一些工具函数获取小时、分钟、年月日,一个用来判定点击了哪个按钮的list(由于是双层结构tab+button集,所以需要两个值来判定),一个获取今天按钮列表的函数:

        getHours() {
            const now = new Date();
            return now.getHours();
        },

        getMinute() {
            const now = new Date();
            return now.getMinutes();
        },

        formatDate(date) {
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            return `${year}-${month}-${day}`;
        },
        
        transTime(arr, day) {
            let temp = []
            arr.forEach((item) => {
                temp.push({
                    lable: item,
                    day: day
                })
            })
            return temp
        },

        getTodayList(arr) {
            let minute = this.getMinute()
            let hour = this.getHours()
            if (hour < 8)
                return arr
            if (hour >= 19 && minute > 30)
                return []
            arr = arr.slice(hour - 7)
            arr = ['一小时内', ...arr]
            return arr
        }

 

然后我们需要先初始化数据

     initial() {
            let minute = this.getMinute()
            let hour = this.getHours()
            if (hour < 8) {
                this.clickValue = "08:00~09:00"
                this.clickDay = "今天"
                return
            }
            if (hour >= 19 && minute > 30) {
                this.clickValue = "08:00~09:00"
                this.clickDay = "明天"
                return
            }
        },

然后将时间赋值,这里其实可以用computed,但是我还是习惯自己做这部分操作

        setTime() {
            this.time = this.clickDay + ' ' + this.clickValue
        },

接下来我们需要生成tab表单dayList,以及每个tab页面下面的时间选项,用了上面的两个工具函数getTodayList(),transTime()

       getDay() {
            const today = new Date()
            const tomorrow = new Date(today)
            tomorrow.setDate(tomorrow.getDate() + 1)
            const afterTomorrow = new Date(today)
            afterTomorrow.setDate(afterTomorrow.getDate() + 2)

            let dayArray = [this.formatDate(today), this.formatDate(tomorrow), this.formatDate(afterTomorrow)]
            let dayName = ['今天', '明天', '后天']
            this.dayList = dayName.map((item, index) => {
                return {
                    lable: item,
                    ymd: dayArray[index]
                }
            })
        },

      getTimeToList() {
            this.dayList.forEach((item) => {
                let arr = JSON.parse(JSON.stringify(this.listArray))
                if (item.lable === "今天")
                    arr = this.getTodayList(arr)
                this.timeToList[item.lable] = this.transTime(arr, item.lable)
            })
        },

通过上面的初始化函数,可以生成下拉页面的组件内容,函数顺序如下

    mounted() {
        this.initial()
        this.setTime()
        this.getDay()
        this.getTimeToList()
    },

最后我们添加一些点击动作,完整代码


        openDown() {//打开下来框
            this.isDropdown = true
        },

        clickoutside(e) {//关闭下拉框
            if (!e) {
                this.isDropdown = false
                this.timeValue = this.clickDay
            }
        },

        dayChange(item) {//切换tab页面
            this.timeValue = item.lable
        },

        timeChange(item) {//选择下单时间
            this.clickValue = item.lable
            this.clickDay = item.day
            this.setTime()
        },

贴一下css代码

<style lang="scss" scoped>
.time-picker {
    background-color: #f4f5f7;
    width: 336px;
    height: 32px;
    padding: 0 6px;

    display: flex;
    justify-content: space-between;
    cursor: pointer;

    .content-first {
        display: flex;
        align-items: center;
        gap: 3px;

        .redSpan {
            color: red;
        }
    }

    .dropdown {
        position: absolute;
        top: 32px;
        right: 0px;
        z-index: 99;
        width: 100%;
        height: 220px;
        background-color: #fff;
        box-shadow: 0 8px 12px 0 rgba(0, 0, 0, 0.04);
        border-radius: 10px;
        padding: 6px;

        .time {
            display: flex;

            .item {
                width: 33%;
                height: 45px;
                text-align: center;
                font-size: 14px;
                line-height: 18px;
                border-bottom: 1px solid #cccccc;
            }

            .active {
                color: red;
                border-bottom: 1px solid red;
            }
        }

        .timeList {
            padding: 10px;
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 10px;

            .timeBox {
                width: 93px;
                height: 29px;
                background-color: #f7f8fa;
                text-align: center;
            }

            .timeBox:hover {
                color: red;
            }

            .active {
                color: red;
                background-color: #ffefef;
            }
        }
    }

}
</style>

完整代码已经上传github:https://github.com/majinihao123/vue-Component

有需要的自取,麻烦给git一个星星!!!

以后要开始好好搞github自己的个人项目了

Logo

前往低代码交流专区

更多推荐