el-time-picker实现分钟时间间隔
2019-08-15 本文已影响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
包进行替换即可生效,如果未生效,具体的修改源码方法可以参考这里