当前位置:   article > 正文

uni-app(微信小程序)自定义日期选择器和时间选择器,解决IOS端和安卓端显示不同问题_uniapp配送时间选择器,可以选择今天和明天,默认选择当前时间 过去的时间不能选中

uniapp配送时间选择器,可以选择今天和明天,默认选择当前时间 过去的时间不能选中

uni-app自定义日期选择器和时间选择器,解决IOS端和安卓端显示不同问题

描述:

原本用的原生组件picker,设置了开始时间和结束时间,安卓端可以显示可选日期时间部分,但是IOS显示的内容包括一整天时间和N个年,本来只需要选择其中七天,那么其他天不显示,IOS端可以滑到其他日期位置,但是会自己滚回来

IOS端:

在这里插入图片描述

在这里插入图片描述

安卓:

在这里插入图片描述
这里只需要八点后和19点前(8:00-19:00)的时间

因此改成自定义自写的组件
在这里插入图片描述
在这里插入图片描述

代码:

日期选择:

<template>
  <view>
    <view v-show="propDate">
      <view class="win-container">
        <view class="win-mask" />
        <view class="win-content">
          <uni-popup ref="popup" type="bottom">
            <view class="operation-title">
              <view class="cancel" @click="cancel">取消</view>
              <view class="title">选择日期</view>
              <view class="confirm" @click="okBtnTime">确定</view>
            </view>
            <picker-view
              indicator-style="height: 50px;"
              style="width: 100%; height: 300px;"
              :value="value"
              @change="bindChange"
            >
              <picker-view-column>
                <view v-for="(item, index) in years" :key="index" style="line-height: 50px; text-align: center;">{{ item }}年</view>
              </picker-view-column>
              <picker-view-column>
                <view v-for="(item, index) in months" :key="index" style="line-height: 50px; text-align: center;">{{ item }}月
                </view>
              </picker-view-column>
              <picker-view-column>
                <view v-for="(item, index) in days" :key="index" style="line-height: 50px; text-align: center;">{{ item }}日</view>
              </picker-view-column>
            </picker-view>
          </uni-popup>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    firstDay: {
      type: [String, Number],
      default: 0
    }
  },
  data() {
    // const date = new Date() // 获取系统日期
    const years = []
    const months = []
    const days = []

    console.log('年月日转换为时间戳:[当前日期][七天后]', this.fun_date(this.firstDay), this.fun_date(this.firstDay + 6))
    const startDate = this.fun_date(this.firstDay).split('-').map(Number)
    const endDate = this.fun_date(this.firstDay + 6).split('-').map(Number)

    const getYear = startDate[0]
    const getMonth = startDate[1]
    const getDate = startDate[2]

    // 年
    console.log('获取年份', startDate[0], endDate[0])
    if (startDate[0] !== endDate[0]) {
      for (let i = startDate[0]; i <= endDate[0]; i++) {
        years.push(i)
      }
    } else {
      years.push(startDate[0])
    }

    // 月
    console.log('获取月份', startDate[1], endDate[1])
    if (startDate[1] !== endDate[1]) {
      for (let i = startDate[1]; i <= endDate[1]; i++) {
        months.push(i)
      }
    } else {
      months.push(startDate[1])
    }

    // 日
    console.log('获取天', startDate[2], endDate[2])
    if (startDate[2] < endDate[2]) {
      for (let i = startDate[2]; i <= endDate[2]; i++) {
        days.push(i)
      }
    } else {
      for (let i = startDate[2]; i <= 31; i++) {
        days.push(i)
      }
    }

    return {
      years: years,
      year: getYear,
      months: months,
      month: getMonth,
      days: days,
      day: getDate,
      value: [0, 0, 0],
      isDaytime: true,
      timeInput: '',
      propDate: false,
      returnDate: []
    }
  },
  watch: {
    visible: {
      handler(val) {
        this.propDate = val
        this.dateMainBtn()
      }
    }
  },
  mounted() {
    console.log('日期弹窗show')
    this.dateMainBtn()
  },
  methods: {
    fun_date(aa) {
      const date1 = new Date()
      // const time1 = date1.getFullYear() + '-' + (date1.getMonth() + 1) + '-' + date1.getDate() // time1表示当前时间
      var date2 = new Date(date1)
      date2.setDate(date1.getDate() + aa)
      const time2 = date2.getFullYear() + '-' + (date2.getMonth() + 1) + '-' + date2.getDate()
      return time2
    },
    // 将日期分开写入对应数组

    dateMainBtn() {
      const setYear = this.year
      const setMonth = this.month
      const setDay = this.day
      const dateTimeBody = setYear + '-' + setMonth + '-' + setDay
      this.returnDate = [setYear, setMonth, setDay]
      console.log('日期弹窗默认数据', dateTimeBody)
    },
    okBtnTime() {
      console.log('日期数组', this.returnDate)
      this.$emit('change', this.returnDate)
      this.$emit('update:visible', false)
      this.timeInput = wx.getStorageSync('adminDate') + wx.getStorageSync('adminTodays')
    },
    cancel() {
      this.$emit('update:visible', false)
    },
    // 判断元素是否在一个数组
    contains(arr, obj) {
      var i = arr.length
      while (i--) {
        if (arr[i] === obj) {
          return true
        }
      }
      return false
    },
    setDays(satrtDay, endDay) {
      const temp = []
      for (let i = satrtDay; i <= endDay; i++) {
        temp.push(i)
      }
      this.days = temp
    },
    // 选择滚动器改变触发事件
    bindChange(e) {
      const bigMonth = [1, 3, 5, 7, 8, 10, 12]
      const val = e.detail.value
      // 判断月的天数
      const setYear = this.years[val[0]]
      const setMonth = this.months[val[1]]

      const startDate = this.fun_date(this.firstDay).split('-').map(Number)
      const endDate = this.fun_date(this.firstDay + 6).split('-').map(Number)
      // 闰年
      if (startDate[1] !== endDate[1]) { // (不在同一个月)
        console.log('横跨两个月')
        if (startDate[1] === setMonth) { // 如果开始月份等于选择的月份
          console.log('开始月份等于选择的月份', startDate[1], setMonth)
          if (setMonth === 2) { // 2月特殊处理
            if (setYear % 4 === 0 && setYear % 100 !== 0) {
              console.log('闰年')
              this.setDays(startDate[2], 29)
            } else {
              console.log('非闰年')
              this.setDays(startDate[2], 28)
            }
          } else { // 非2月
          // 大月
            if (this.contains(bigMonth, setMonth)) {
              this.setDays(startDate[2], 31)
            } else {
              this.setDays(startDate[2], 30)
            }
          }
        } else if (endDate[1] === setMonth) { // 如果结束月份等于选择的月份
          console.log('结束月份等于选择的月份', endDate[2])
          this.setDays(1, endDate[2])
        }
      } else { // 在同一个月
        this.setDays(startDate[2], endDate[2])
      }
      const setDay = this.days[val[2]]
      this.year = setYear
      this.month = setMonth
      this.day = setDay
      this.isDaytime = !val[3]
      const dateTimeBody = setYear + '-' + setMonth + '-' + setDay
      console.log('滑动后的日期', dateTimeBody)
      this.returnDate = [setYear, setMonth, setDay]
      wx.setStorageSync('adminDate', dateTimeBody)
    }
  }
}
</script>

<style lang="scss" scoped>
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}
.win-container {
  bottom: 0;
  width: 100%;
  font-size: 32rpx;
  @extend .center;
  position: fixed;
  z-index: 20;
  left: 0;

  .win-mask {
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.6);
    z-index: 20;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
  }

  .win-content {
    width: 100%;
    max-height: 60vh;
    position: absolute;
    // overflow: auto;
    bottom: 0;
    left: 0;
    // @extend .center;
    background-color: #FFFFFF;
    z-index: 21;
    border-radius: 32rpx 32rpx 0 0;
    .operation-title {
      @extend .center;
      height: 136rpx;
      font-size: 32rpx;
      font-weight: bold;
      align-items: center;
      view {
        flex: 1;
        text-align: center;
      }
      .title {
        font-size: 36rpx;
      }
      .cancel {
        color: #666666;
      }
      .confirm {
        color: #2E4CFF;
      }
    }
  }
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278

时间选择

<template>
  <view>
    <view v-show="show">
      <view class="win-container">
        <view class="win-mask" />
        <view class="win-content">
          <uni-popup ref="popup" type="bottom">
            <view class="operation-title">
              <view class="cancel" @click="cancel">取消</view>
              <view class="title">选择日期</view>
              <view class="confirm" @click="confirm">确定</view>
            </view>
            <picker-view
              class="picker-view"
              :indicator-style="indicatorStyle"
              :value="value"
              @change="bindChange"
            >
              <picker-view-column>
                <view v-for="(item,index) in hours" :key="index" class="item">{{ item }}时</view>
              </picker-view-column>
              <picker-view-column>
                <view v-for="(item,index) in minutes" :key="index" class="item">{{ item }}分</view>
              </picker-view-column>
            </picker-view>
          </uni-popup>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    isThisToday: {
      type: Boolean,
      default: false
    }
  },
  data() {
    const date = new Date()
    const hours = []
    const hour = date.getHours() + 1
    const minutes = []
    const minute = date.getMinutes()
    console.log('hour', hour)
    for (let i = 8; i <= 19; i++) {
      if (i < 10) {
        hours.push('0' + i)
      } else {
        hours.push(i)
      }
    }
    for (let i = 0; i <= 59; i++) {
      if (i < 10) {
        minutes.push('0' + i)
      } else {
        minutes.push(i)
      }
    }
    return {
      hours,
      minutes,
      hour,
      minute,
      value: [0, 0],
      show: false,
      indicatorStyle: `height: 50px;`,
      maskStyle: 'padding:10px 0'
    }
  },
  watch: {
    visible: {
      handler(val) {
        this.show = val
      }
    },
    isThisToday: {
      handler(val) {
        if (val) {
          this.setHours(this.getNowTime()[0], 19)
          this.setMinutes(this.getNowTime()[1], 59)
          const setHour = this.hour
          const setMinute = this.minute
          this.value = [this.hours.map(Number).map(item => item).indexOf(setHour), this.minutes.map(Number).map(item => item).indexOf(setMinute)]
        } else {
          this.setHours(8, 19)
          this.setMinutes(0, 59)
          const setHour = this.hour
          const setMinute = this.minute
          this.value = [this.hours.map(Number).map(item => item).indexOf(setHour), this.minutes.map(Number).map(item => item).indexOf(setMinute)]
        }
        console.log('日期选择了当天', val)
      }
    }
  },
  mounted() {
    this.timeMainBtn()
  },
  methods: {
    timeMainBtn() {
      const setHour = this.hour
      const setMinute = this.minute
      const dateTimeBody = setHour + '时' + setMinute + '分'
      this.returnTime = setHour + ':' + setMinute
      this.value = [this.hours.map(Number).map(item => item).indexOf(setHour), this.minutes.map(Number).map(item => item).indexOf(setMinute)]
      console.log('时间弹窗默认数据', dateTimeBody, this.value)
    },
    bindChange(e) {
      const val = e.detail.value

      const setHour = this.hours[val[0]]
      if (setHour === 19) {
        this.minutes = ['00']
      } else if ((parseInt(setHour) === this.getNowTime()[0]) && this.isThisToday) {
        this.setMinutes(this.getNowTime()[1], 59)
      } else {
        this.setMinutes(0, 59)
      }
      const setMinute = this.minutes[val[1]]
      this.value = val
      console.log('this.value', this.value)
      console.log('选择了时间', setHour + '时' + setMinute + '分', '现在的时间', ((parseInt(setHour) === this.getNowTime()[0] + 1) && this.isThisToday))
    },
    setHours(satrtHour, endHour) {
      const res = []
      for (let i = satrtHour; i <= endHour; i++) {
        if (i < 10) {
          res.push('0' + i)
        } else {
          res.push(i)
        }
      }
      this.hours = res
    },
    setMinutes(satrtMinute, endMinute) {
      const temp = []
      for (let i = satrtMinute; i <= endMinute; i++) {
        if (i < 10) {
          temp.push('0' + i)
        } else {
          temp.push(i)
        }
      }
      this.minutes = temp
    },
    cancel() {
      this.$emit('update:visible', false)
    },
    confirm() {
      this.returnTime = this.hours[this.value[0]] + ':' + this.minutes[this.value[1]]
      console.log('现在选择的时间', this.returnTime)
      this.$emit('change', this.returnTime)
      this.$emit('update:visible', false)
    },
    // 获取当前时间
    getNowTime() {
      const date = new Date()
      const hour = date.getHours() + 1
      // hour < 10 ? '0' + date.getHours() : date.getHours()
      console.log('当前时间的小时 ', hour)
      const minute = date.getMinutes()
      // const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
      return [hour, minute]
    }
  }
}
</script>

<style lang="scss" scoped>
picker-view {
  width: 100%;
  height: 600rpx;
  margin-top: 20rpx;
}
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.item {
  line-height: 100rpx;
  text-align: center;
}
.win-container {
  bottom: 0;
  width: 100%;
  font-size: 32rpx;
  @extend .center;
  position: fixed;
  z-index: 20;
  left: 0;

  .win-mask {
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.6);
    z-index: 20;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
  }

  .win-content {
    width: 100%;
    max-height: 80vh;
    position: absolute;
    overflow: auto;
    bottom: 0;
    left: 0;
    // @extend .center;
    background-color: #FFFFFF;
    z-index: 21;
    border-radius: 32rpx 32rpx 0 0;
    .operation-title {
      @extend .center;
      height: 96rpx;
      font-size: 32rpx;
      font-weight: bold;
      view {
        flex: 1;
        text-align: center;
      }
      .title {
        font-size: 36rpx;
      }
      .cancel {
        color: #666666;
      }
      .confirm {
        color: #2E4CFF;
      }
    }
  }
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244

组件使用:

只展示部分,其他的自己补全

    <date-picker :visible.sync="visibleDate" :first-day="startDay" @change="getCheckDate" />
    <time-picker :visible.sync="visibleTime" :is-this-today="isThisToday" @change="getCheckTime" />
  • 1
  • 2

import TimePicker from '@/components/modal-v2/time-picker'
import DatePicker from '@/components/modal-v2/date-picker.vue'

  components: {
    TimePicker,
    DatePicker
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
// 打开日期弹窗
    selectDate() {
      this.visibleDate = true
    },
    // 打开时间弹窗
    selectTime() {
      this.visibleTime = true
    },
    // 选择日期
    getCheckDate(val) {
      const date = val.join('-')
      console.log('getCheckDate', val, '传递回去的日期', date)
      this.$emit('dateSelect', date)
      if (date === this.getDate('start')) { // 如果选择的日期是当天的话
        this.isThisToday = true // 告诉组件选择了今天时间得限制
        // 判断当前时间是否符合时间段
        if (this.checkAuditTime('07:00', '18:00')) {
          this.time = ''
          this.$emit('timeSelect', '')
        } else {
          // this.startTime = '08:00'
        }
      } else {
        this.isThisToday = false // 告诉组件选择了今天时间得限制
      }
      this.date = val[0] + '年' + val[1] + '月' + val[2] + '日'
    },
    // 时间弹窗选择了时间
    getCheckTime(time) {
      this.$emit('timeSelect', time)
      const selectTime = time
      this.time = selectTime.split(':')[0] + '时' + selectTime.split(':')[1] + '分'
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/306545
推荐阅读
相关标签
  

闽ICP备14008679号