美文网首页
el-time-picker实现分钟时间间隔

el-time-picker实现分钟时间间隔

作者: 辉夜真是太可爱啦 | 来源:发表于2019-08-15 15:47 被阅读0次

    效果如图,时间级联选择器实现分钟只能选择00,15,30以及45分钟,由于没有相关的api,我采用的方法是直接修改源码

    设置分钟间隔

    将它设置为arrow-control,并且设置一个默认值

     <el-time-picker arrow-control :default-value="[new Date(2016, 9, 10, 8, 15), new Date(2016, 9, 10, 9, 30)]"  is-range  format="HH:mm"  value-format="HH:mm" v-model="time"></el-time-picker>
    

    1.新建一个文件夹,从git上拉取element的源码

    git clone https://github.com/ElemeFE/element.git
    

    2.安装依赖npm install

    3.找到packages\date-picker\src\basic\time-spinner.vue,将以下代码进行完全替换,你需要设置的间隔时长step只需要修改四处即可,我都在其中加上了注释

    <template>
      <div class="el-time-spinner" :class="{ 'has-seconds': showSeconds }">
        <template v-if="!arrowControl">
          <el-scrollbar
            @mouseenter.native="emitSelectRange('hours')"
            @mousemove.native="adjustCurrentSpinner('hours')"
            class="el-time-spinner__wrapper"
            wrap-style="max-height: inherit;"
            view-class="el-time-spinner__list"
            noresize
            tag="ul"
            ref="hours">
            <li
              @click="handleClick('hours', { value: hour, disabled: disabled })"
              v-for="(disabled, hour) in hoursList"
              class="el-time-spinner__item"
              :key="hour"
              :class="{ 'active': hour === hours, 'disabled': disabled }">{{ ('0' + (amPmMode ? (hour % 12 || 12) : hour )).slice(-2) }}{{ amPm(hour) }}</li>
          </el-scrollbar>
          <el-scrollbar
            @mouseenter.native="emitSelectRange('minutes')"
            @mousemove.native="adjustCurrentSpinner('minutes')"
            class="el-time-spinner__wrapper"
            wrap-style="max-height: inherit;"
            view-class="el-time-spinner__list"
            noresize
            tag="ul"
            ref="minutes">
            <li
              @click="handleClick('minutes', { value: key, disabled: false })"
              v-for="(enabled, key) in minutesList"
              :key="key"
              class="el-time-spinner__item"
              :class="{ 'active': key === minutes, disabled: !enabled }">{{ ('0' + key).slice(-2) }}</li>
          </el-scrollbar>
          <el-scrollbar
            v-show="showSeconds"
            @mouseenter.native="emitSelectRange('seconds')"
            @mousemove.native="adjustCurrentSpinner('seconds')"
            class="el-time-spinner__wrapper"
            wrap-style="max-height: inherit;"
            view-class="el-time-spinner__list"
            noresize
            tag="ul"
            ref="seconds">
            <li
              @click="handleClick('seconds', { value: key, disabled: false })"
              v-for="(second, key) in 60"
              class="el-time-spinner__item"
              :class="{ 'active': key === seconds }"
              :key="key">{{ ('0' + key).slice(-2) }}</li>
          </el-scrollbar>
        </template>
        <template v-if="arrowControl">
          <div
            @mouseenter="emitSelectRange('hours')"
            class="el-time-spinner__wrapper is-arrow">
            <i v-repeat-click="decrease" class="el-time-spinner__arrow el-icon-arrow-up"></i>
            <i v-repeat-click="increase" class="el-time-spinner__arrow el-icon-arrow-down"></i>
            <ul class="el-time-spinner__list" ref="hours">
              <li
                class="el-time-spinner__item"
                :class="{ 'active': hour === hours, 'disabled': hoursList[hour] }"
                v-for="(hour, key) in arrowHourList"
                :key="key">{{ hour === undefined ? '' : ('0' + (amPmMode ? (hour % 12 || 12) : hour )).slice(-2) + amPm(hour) }}</li>
            </ul>
          </div>
          <div
            @mouseenter="emitSelectRange('minutes')"
            class="el-time-spinner__wrapper is-arrow">
            <i v-repeat-click="decreaseMinute" class="el-time-spinner__arrow el-icon-arrow-up"></i>
            <i v-repeat-click="increaseMinute" class="el-time-spinner__arrow el-icon-arrow-down"></i>
            <ul class="el-time-spinner__list" ref="minutes">
              <li
                class="el-time-spinner__item"
                :class="{ 'active': minute === minutes }"
                v-for="(minute, key) in arrowMinuteList"
                :key="key">
                {{ minute === undefined ? '' : ('0' + minute).slice(-2) }}
              </li>
            </ul>
          </div>
          <div
            @mouseenter="emitSelectRange('seconds')"
            class="el-time-spinner__wrapper is-arrow"
            v-if="showSeconds">
            <i v-repeat-click="decrease" class="el-time-spinner__arrow el-icon-arrow-up"></i>
            <i v-repeat-click="increase" class="el-time-spinner__arrow el-icon-arrow-down"></i>
            <ul class="el-time-spinner__list" ref="seconds">
              <li
                v-for="(second, key) in arrowSecondList"
                class="el-time-spinner__item"
                :class="{ 'active': second === seconds }"
                :key="key">
                {{ second === undefined ? '' : ('0' + second).slice(-2) }}
              </li>
            </ul>
          </div>
        </template>
      </div>
    </template>
    
    <script type="text/babel">
      import { getRangeHours, getRangeMinutes, modifyTime } from 'element-ui/src/utils/date-util';
      import ElScrollbar from 'element-ui/packages/scrollbar';
      import RepeatClick from 'element-ui/src/directives/repeat-click';
    
      export default {
        components: { ElScrollbar },
    
        directives: {
          repeatClick: RepeatClick
        },
    
        props: {
          date: {},
          defaultValue: {}, // reserved for future use
          showSeconds: {
            type: Boolean,
            default: true
          },
          arrowControl: Boolean,
          amPmMode: {
            type: String,
            default: '' // 'a': am/pm; 'A': AM/PM
          }
        },
    
        computed: {
          hours() {
            return this.date.getHours();
          },
          minutes() {
            return this.date.getMinutes();
          },
          seconds() {
            return this.date.getSeconds();
          },
          hoursList() {
            return getRangeHours(this.selectableRange);
          },
          minutesList() {
            return getRangeMinutes(this.selectableRange, this.hours);
          },
          arrowHourList() {
            const hours = this.hours;
            return [
              hours > 0 ? hours - 1 : undefined,
              hours,
              hours < 23 ? hours + 1 : undefined
            ];
          },
          arrowMinuteList() {
            const minutes = this.minutes;
            return [
              minutes > 0 ? minutes - 15 : undefined,     //15为我设置的step
              minutes,
              minutes < 60 ? minutes + 15 : undefined    //15为我设置的step,60为我设置的上限
            ];
          },
          arrowSecondList() {
            const seconds = this.seconds;
            return [
              seconds > 0 ? seconds - 1 : undefined,
              seconds,
              seconds < 59 ? seconds + 1 : undefined
            ];
          }
        },
    
        data() {
          return {
            selectableRange: [],
            currentScrollbar: null
          };
        },
    
        mounted() {
          this.$nextTick(() => {
            !this.arrowControl && this.bindScrollEvent();
          });
        },
    
        methods: {
          increase() {
            this.scrollDown(1);
          },
          increaseMinute() {
            this.scrollDown(15);     //将里面的数值设为你的step
          },
    
          decrease() {
            this.scrollDown(-1);
          },
          decreaseMinute() {
            this.scrollDown(-15);   //将里面的数值设为你的step
          },
    
          modifyDateField(type, value) {
            switch (type) {
              case 'hours': this.$emit('change', modifyTime(this.date, value, this.minutes, this.seconds)); break;
              case 'minutes': this.$emit('change', modifyTime(this.date, this.hours, value, this.seconds)); break;
              case 'seconds': this.$emit('change', modifyTime(this.date, this.hours, this.minutes, value)); break;
            }
          },
    
          handleClick(type, {value, disabled}) {
            if (!disabled) {
              this.modifyDateField(type, value);
              this.emitSelectRange(type);
              this.adjustSpinner(type, value);
            }
          },
    
          emitSelectRange(type) {
            if (type === 'hours') {
              this.$emit('select-range', 0, 2);
            } else if (type === 'minutes') {
              this.$emit('select-range', 3, 5);
            } else if (type === 'seconds') {
              this.$emit('select-range', 6, 8);
            }
            this.currentScrollbar = type;
          },
    
          bindScrollEvent() {
            const bindFuntion = (type) => {
              this.$refs[type].wrap.onscroll = (e) => {
                // TODO: scroll is emitted when set scrollTop programatically
                // should find better solutions in the future!
                this.handleScroll(type, e);
              };
            };
            bindFuntion('hours');
            bindFuntion('minutes');
            bindFuntion('seconds');
          },
    
          handleScroll(type) {
            const value = Math.min(Math.floor((this.$refs[type].wrap.scrollTop - (this.scrollBarHeight(type) * 0.5 - 10) / this.typeItemHeight(type) + 3) / this.typeItemHeight(type)), (type === 'hours' ? 23 : 59));
            this.modifyDateField(type, value);
          },
    
          // NOTE: used by datetime / date-range panel
          //       renamed from adjustScrollTop
          //       should try to refactory it
          adjustSpinners() {
            this.adjustSpinner('hours', this.hours);
            this.adjustSpinner('minutes', this.minutes);
            this.adjustSpinner('seconds', this.seconds);
          },
    
          adjustCurrentSpinner(type) {
            this.adjustSpinner(type, this[type]);
          },
    
          adjustSpinner(type, value) {
            if (this.arrowControl) return;
            const el = this.$refs[type].wrap;
            if (el) {
              el.scrollTop = Math.max(0, value * this.typeItemHeight(type));
            }
          },
    
          scrollDown(step) {
            if (!this.currentScrollbar) {
              this.emitSelectRange('hours');
            }
    
            const label = this.currentScrollbar;
            const hoursList = this.hoursList;
            let now = this[label];
    
            if (this.currentScrollbar === 'hours') {
              let total = Math.abs(step);
              step = step > 0 ? 1 : -1;
              let length = hoursList.length;
              while (length-- && total) {
                now = (now + step + hoursList.length) % hoursList.length;
                if (hoursList[now]) {
                  continue;
                }
                total--;
              }
              if (hoursList[now]) return;
            } else {
              now = (now + step + 60) % 60;
            }
    
            this.modifyDateField(label, now);
            this.adjustSpinner(label, now);
          },
          amPm(hour) {
            let shouldShowAmPm = this.amPmMode.toLowerCase() === 'a';
            if (!shouldShowAmPm) return '';
            let isCapital = this.amPmMode === 'A';
            let content = (hour < 12) ? ' am' : ' pm';
            if (isCapital) content = content.toUpperCase();
            return content;
          },
          typeItemHeight(type) {
            return this.$refs[type].$el.querySelector('li').offsetHeight;
          },
          scrollBarHeight(type) {
            return this.$refs[type].$el.offsetHeight;
          }
        }
      };
    </script>
    

    4.修改完之后运行npm run dist进行打包

    5.找到你的项目中的node_modules包下的element-ui文件夹下的lib包,用你修改好后打包生成的lib包进行替换即可生效,如果未生效,具体的修改源码方法可以参考这里

    相关文章

      网友评论

          本文标题:el-time-picker实现分钟时间间隔

          本文链接:https://www.haomeiwen.com/subject/fomzjctx.html