插件窝 干货文章 vue2.0+elementui实现一个上门取件时间组件

vue2.0+elementui实现一个上门取件时间组件

class div item gt 517    来源:    2024-10-18

本文使用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(null, '0');
            const day = String(date.getDate()).padStart(null, '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(null, 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

总结

到此这篇关于vue2.0+elementui实现一个上门取件时间组件的文章就介绍到这了,更多相关Vue上门取件时间组件内容请搜索插件窝以前的文章或继续浏览下面的相关文章希望大家以后多多支持插件窝!