本文使用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 arrif (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 < 9) {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 = falsethis.timeValue = this.clickDay}},dayChange(item) {//切换tab页面this.timeValue = item.lable},timeChange(item) {//选择下单时间this.clickValue = item.lablethis.clickDay = item.daythis.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自己的个人项目了