123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- <template>
- <view :style="{height: height + 'px'}" class="wk-date-picker picker">
- <view class="picker-header">
- <view class="cancel" @click="handleCancel">
- 取消
- </view>
- <view class="picker-header-title" />
- <view class="confirm" @click="handleConfirm">
- 确认
- </view>
- </view>
-
- <picker-view
- v-if="showPicker"
- v-model="valueIndexArr"
- indicator-class="indicator-active"
- class="picker-body"
- @change="bindChange">
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in years" :key="index" class="picker-item">
- {{ item }}年
- </view>
- </picker-view-column>
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in months" :key="index" class="picker-item">
- {{ item }}月
- </view>
- </picker-view-column>
-
- <template v-if="type !== 'month'">
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in days" :key="index" class="picker-item">
- {{ item }}日
- </view>
- </picker-view-column>
- </template>
-
- <template v-if="type === 'datetime'">
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in hours" :key="index" class="picker-item">
- {{ item }}时
- </view>
- </picker-view-column>
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in minutes" :key="index" class="picker-item">
- {{ item }}分
- </view>
- </picker-view-column>
- <picker-view-column class="picker-body-column">
- <view v-for="(item,index) in seconds" :key="index" class="picker-item">
- {{ item }}秒
- </view>
- </picker-view-column>
- </template>
- </picker-view>
- </view>
- </template>
- <script>
- import moment from 'moment'
- export default {
- name: 'WkDatePicker',
- inject: ['popup'],
- props: {
- value: {
- type: String,
- default: null
- },
- type: {
- type: String,
- validator: val => {
- return ['date', 'datetime', 'month'].includes(val)
- },
- required: true
- },
- startTime: {
- type: String,
- default: null
- },
- endTime: {
- type: String,
- default: null
- }
- },
- data() {
- return {
- height: 0,
- valueArr: [],
- valueIndexArr: [],
- years: [],
- months: [],
- days: [],
- hours: [],
- minutes: [],
- seconds: [],
-
- maxDate: [],
- minDate: [],
-
- showPicker: false
- }
- },
- watch: {
- value() {
- this.initDate()
- }
- },
- mounted() {
- this.initDate()
- const that = this
- uni.getSystemInfo({
- success: res => {
- that.height = res.windowHeight * 0.4
- }
- })
- },
- methods: {
- /**
- * 初始化
- */
- initDate() {
- this.valueArr = this.dateToArr(this.value)
- this.hours = Array.from({length: 24}, (v, k) => k)
- this.minutes = Array.from({length: 60}, (v, k) => k)
- this.seconds = Array.from({length: 60}, (v, k) => k)
-
- // 计算结束日期
- if (!this.endTime) {
- const arr = this.dateToArr(this.endTime)
- // console.log('arr: ', arr)
- // arr[0] = arr[0] + 50
- arr[0] = arr[0] + 100
- this.maxDate = [arr[0], 12, 31, 23, 59, 59]
- } else {
- this.maxDate = this.dateToArr(this.endTime)
- }
-
- // 计算开始日期
- if (!this.startTime) {
- // this.minDate = [1900,1,1,0,0,0]
- const now = this.dateToArr()
- this.minDate = [now[0] - 100, 1, 1, 0, 0, 0]
- } else {
- this.minDate = this.dateToArr(this.startTime)
- }
- this.getYears()
- this.getMonths()
- this.getDays()
-
- this.showPicker = false
- // 获取初始位置
- this.$nextTick(() => {
- const arr = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']
- this.valueArr.forEach((v, i) => {
- const findIndex = this[arr[i]].findIndex(o => o === v)
- this.$set(this.valueIndexArr, i, findIndex)
- })
- this.showPicker = true
- })
- },
-
- /**
- * 日期转数组
- * @param {Object} date
- */
- dateToArr(date) {
- if (!date) date = new Date()
- return moment(date).format('YYYY-MM-DD-HH-mm-ss').split('-').map(o => Number(o))
- },
-
- /**
- * 获取年份列表
- */
- getYears() {
- let list = []
- let i = this.minDate[0]
- do {
- list.push(i)
- i++
- } while (i <= this.maxDate[0])
- this.years = list
- // 计算年份位置
- this.$set(this.valueIndexArr, 0, this.valueArr[0] - this.minDate[0])
- },
-
- /**
- * 获取月份列表
- */
- getMonths() {
- const list = Array.from({length: 12}, (v, k) => k + 1)
- const year = this.valueArr[0]
- const minYear = this.years[0]
- const maxYear = this.years[this.years.length - 1]
- let min = 1 // 最小的月份
- let max = 12 // 最大的月份
- if (year === minYear) {
- min = this.minDate[1]
- } else {
- min = 1
- }
- if (year === maxYear) {
- max = this.maxDate[1]
- } else {
- max = 12
- }
- this.months = list.slice(min - 1, max - min + 1)
- // 计算月份位置
- const findIndex = this.months.findIndex(o => o === this.valueArr[1])
- if (findIndex !== -1) {
- this.$set(this.valueIndexArr, 1, findIndex)
- } else {
- this.valueArr[1] = this.months[this.months.length - 1]
- this.$set(this.valueIndexArr, 1, this.months.length - 1)
- }
- this.getDays()
- },
-
- /**
- * 获取天数列表
- */
- getDays() {
- let arr = []
- let list = [1, 3, 5, 7, 8, 10, 12]
- let start = 1, end = 1;
- let index = list.findIndex(item => {
- return this.valueArr[1] === item
- });
- if (index !== -1) {
- end = 31
- } else if (this.valueArr[1] !== 2) {
- end = 30
- } else if ((this.valueArr[0] % 4 === 0 && this.valueArr[0] % 100 !== 0) || this.valueArr[0] % 400 === 0) {
- // 闰年
- end = 29
- } else {
- end = 28
- }
- do {
- arr.push(start)
- start++;
- } while (start <= end)
- this.days = arr
- // 计算天数位置
- const findIndex = this.days.findIndex(o => o === this.valueArr[2])
- if (findIndex !== -1) {
- this.$set(this.valueIndexArr, 2, findIndex)
- } else {
- this.valueArr[2] = this.days[this.days.length - 1]
- this.$set(this.valueIndexArr, 2, this.days.length - 1)
- }
- },
- bindChange({ detail }) {
- const arr = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']
- detail.value.forEach((item, index) => {
- if (this.valueIndexArr[index] !== item) {
- if (index === 0) {
- this.valueArr[0] = this.years[item]
- this.getMonths()
- } else if (index === 1) {
- this.valueArr[1] = this.months[item]
- this.getDays()
- } else {
- this.valueArr[index] = this[arr[index]][item]
- }
- this.valueIndexArr[index] = item
- }
- })
- },
- handleConfirm() {
- console.log('valueArr:', this.valueArr)
- console.log('valueIndexArr: ', this.valueIndexArr)
- const arr = [...this.valueArr]
- arr[1] = arr[1] - 1
- let date = moment(arr)
- if (this.type === 'date') {
- date = date.format('YYYY-MM-DD')
- } else if (this.type === 'datetime') {
- date = date.format('YYYY-MM-DD HH:mm:ss')
- } else if (this.type === 'month') {
- date = date.format('YYYY-MM')
- }
- console.log(' date,: ', date)
- this.$emit('input', date)
- this.$emit('select', date, () => {
- this.popup.close()
- })
- },
- handleCancel() {
- this.popup.close()
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .picker {
- width: 100%;
- background-color: white;
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- .picker-header {
- height: 70rpx;
- font-size: 26rpx;
- border-bottom: 1rpx solid $border-color;
- padding: 0 30rpx;
- @include left;
-
- .picker-header-title {
- flex: 1;
- }
- .cancel {
- color: #666666;
- }
- .confirm {
- color: $theme-color;
- }
- }
-
- .picker-body {
- flex: 1;
- padding: 0 30rpx;
- .picker-view {
- width: 100%;
- height: 100%;
- }
- .picker-body-column {
- .picker-item {
- font-size: 26rpx;
- @include center;
- }
- }
- }
- }
- </style>
|