support DatePicker & TimePicker

support DatePicker & TimePicker
This commit is contained in:
梁灏 2017-03-07 18:06:56 +08:00
parent 5b19b5f55f
commit 531cd1654b
19 changed files with 265 additions and 79 deletions

View file

@ -1,7 +1,7 @@
### Button
可以考虑是否支持 @click,而不用 @click.native
### Input
使用 v-model
使用 v-model,增加 on-input-change // todo 考虑更名
### RadioGroup
使用 v-model
### Radio
@ -45,3 +45,4 @@ Caspanel 的 sublist 从 prop -> data
model 改为 value支持 v-model
### Page
class 改为 className
### DatePicker

View file

@ -27,10 +27,10 @@
- [ ] Table
- [x] Select
- [x] Slider
- [ ] DatePicker
- [ ] TimePicker
- [x] DatePicker
- [x] TimePicker
- [x] Cascader
- [ ] Transfer
- [x] Transfer
- [x] InputNumber
- [x] Rate
- [x] Upload

View file

@ -47,6 +47,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; }
<li><router-link to="/backtop">Backtop</router-link></li>
<li><router-link to="/page">Page</router-link></li>
<li><router-link to="/transfer">Transfer</router-link></li>
<li><router-link to="/date">Date</router-link></li>
</ul>
</nav>
<router-view></router-view>

View file

@ -152,6 +152,10 @@ const router = new VueRouter({
{
path: '/transfer',
component: require('./routers/transfer.vue')
},
{
path: '/date',
component: require('./routers/date.vue')
}
]
});

View file

@ -1,14 +1,178 @@
<template>
<Date-picker type="datetime" placeholder="选择日期和时间" style="width: 200px"></Date-picker>
<br>
<Date-picker type="datetime" format="yyyy-MM-dd HH:mm" placeholder="选择日期和时间(不含秒)" style="width: 200px"></Date-picker>
<br>
<Date-picker type="datetimerange" placeholder="选择日期和时间" style="width: 300px"></Date-picker>
<br>
<Date-picker type="datetimerange" format="yyyy-MM-dd HH:mm" placeholder="选择日期和时间(不含秒)" style="width: 300px"></Date-picker>
<div>
{{ val1 }}
<Date-picker v-model="val1" type="daterange" placeholder="选择日期" style="width: 200px"></Date-picker>
<div @click="val1 = '2017-03-02'">change</div>
</div>
</template>
<script>
export default {
data () {
return {
val1: ''
}
},
computed: {
ddd () {
const date = new Date(this.val1);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}-${month}-${day}`;
}
}
}
</script>
<!--<template>-->
<!--<row>-->
<!--<i-col span="12">-->
<!--<Date-picker type="date" :options="options1" placeholder="选择日期" style="width: 200px"></Date-picker>-->
<!--</i-col>-->
<!--<i-col span="12">-->
<!--<Date-picker type="daterange" :options="options2" placement="bottom-end" placeholder="选择日期" style="width: 200px"></Date-picker>-->
<!--</i-col>-->
<!--</row>-->
<!--</template>-->
<!--<script>-->
<!--export default {-->
<!--data () {-->
<!--return {-->
<!--options1: {-->
<!--shortcuts: [-->
<!--{-->
<!--text: '今天',-->
<!--value () {-->
<!--return new Date();-->
<!--},-->
<!--onClick: (picker) => {-->
<!--this.$Message.info('点击了今天');-->
<!--}-->
<!--},-->
<!--{-->
<!--text: '昨天',-->
<!--value () {-->
<!--const date = new Date();-->
<!--date.setTime(date.getTime() - 3600 * 1000 * 24);-->
<!--return date;-->
<!--},-->
<!--onClick: (picker) => {-->
<!--this.$Message.info('点击了昨天');-->
<!--}-->
<!--},-->
<!--{-->
<!--text: '一周前',-->
<!--value () {-->
<!--const date = new Date();-->
<!--date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);-->
<!--return date;-->
<!--},-->
<!--onClick: (picker) => {-->
<!--this.$Message.info('点击了一周前');-->
<!--}-->
<!--}-->
<!--]-->
<!--},-->
<!--options2: {-->
<!--shortcuts: [-->
<!--{-->
<!--text: '最近一周',-->
<!--value () {-->
<!--const end = new Date();-->
<!--const start = new Date();-->
<!--start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);-->
<!--return [start, end];-->
<!--}-->
<!--},-->
<!--{-->
<!--text: '最近一个月',-->
<!--value () {-->
<!--const end = new Date();-->
<!--const start = new Date();-->
<!--start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);-->
<!--return [start, end];-->
<!--}-->
<!--},-->
<!--{-->
<!--text: '最近三个月',-->
<!--value () {-->
<!--const end = new Date();-->
<!--const start = new Date();-->
<!--start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);-->
<!--return [start, end];-->
<!--}-->
<!--}-->
<!--]-->
<!--}-->
<!--}-->
<!--}-->
<!--}-->
<!--</script>-->
<!--<template>-->
<!--<row>-->
<!--<i-col span="12">-->
<!--<Date-picker :value="value1" format="yyyy年MM月dd日" type="date" placeholder="选择日期" style="width: 200px"></Date-picker>-->
<!--</i-col>-->
<!--<i-col span="12">-->
<!--<Date-picker :value="value2" format="yyyy/MM/dd" type="daterange" placement="bottom-end" placeholder="选择日期" style="width: 200px"></Date-picker>-->
<!--</i-col>-->
<!--</row>-->
<!--</template>-->
<!--<script>-->
<!--export default {-->
<!--data () {-->
<!--return {-->
<!--value1: '2016-01-01',-->
<!--value2: ['2016-01-01', '2016-02-15']-->
<!--}-->
<!--}-->
<!--}-->
<!--</script>-->
<!--<template>-->
<!--<div>-->
<!--<Date-picker type="datetime" placeholder="选择日期和时间" style="width: 200px"></Date-picker>-->
<!--<br>-->
<!--<Date-picker type="datetime" format="yyyy-MM-dd HH:mm" placeholder="选择日期和时间(不含秒)" style="width: 200px"></Date-picker>-->
<!--<br>-->
<!--<Date-picker type="datetimerange" placeholder="选择日期和时间" style="width: 300px"></Date-picker>-->
<!--<br>-->
<!--<Date-picker type="datetimerange" format="yyyy-MM-dd HH:mm" placeholder="选择日期和时间(不含秒)" style="width: 300px"></Date-picker>-->
<!--</div>-->
<!--</template>-->
<!--<script>-->
<!--export default {-->
<!--}-->
<!--</script>-->
<!--<template>-->
<!--<row>-->
<!--<i-col span="12">-->
<!--<Time-picker type="time" placeholder="选择时间" style="width: 168px"></Time-picker>-->
<!--</i-col>-->
<!--<i-col span="12">-->
<!--<Time-picker type="timerange" placement="bottom-end" placeholder="选择时间" style="width: 168px"></Time-picker>-->
<!--</i-col>-->
<!--</row>-->
<!--</template>-->
<!--<script>-->
<!--export default {-->
<!--data () {-->
<!--return {-->
<!--t1: ''-->
<!--}-->
<!--}-->
<!--}-->
<!--</script>-->

View file

@ -4,8 +4,8 @@
<template v-if="isTime">{{ t('i.datepicker.selectDate') }}</template>
<template v-else>{{ t('i.datepicker.selectTime') }}</template>
</span>
<i-button size="small" type="text" @click="handleClear">{{ t('i.datepicker.clear') }}</i-button>
<i-button size="small" type="primary" @click="handleSuccess">{{ t('i.datepicker.ok') }}</i-button>
<i-button size="small" type="text" @click.native="handleClear">{{ t('i.datepicker.clear') }}</i-button>
<i-button size="small" type="primary" @click.native="handleSuccess">{{ t('i.datepicker.ok') }}</i-button>
</div>
</template>
<script>

View file

@ -6,7 +6,7 @@
<div :class="[prefixCls + '-header']">
<span>{{ t('i.datepicker.weeks.sun') }}</span><span>{{ t('i.datepicker.weeks.mon') }}</span><span>{{ t('i.datepicker.weeks.tue') }}</span><span>{{ t('i.datepicker.weeks.wed') }}</span><span>{{ t('i.datepicker.weeks.thu') }}</span><span>{{ t('i.datepicker.weeks.fri') }}</span><span>{{ t('i.datepicker.weeks.sat') }}</span>
</div>
<span :class="getCellCls(cell)" v-for="cell in readCells"><em :index="$index">{{ cell.text }}</em></span>
<span :class="getCellCls(cell)" v-for="(cell, index) in readCells"><em :index="index">{{ cell.text }}</em></span>
</div>
</template>
<script>

View file

@ -1,6 +1,6 @@
<template>
<div :class="classes" @click="handleClick">
<span :class="getCellCls(cell)" v-for="cell in cells"><em :index="$index">{{ tCell(cell.text) }}</em></span>
<span :class="getCellCls(cell)" v-for="(cell, index) in cells"><em :index="index">{{ tCell(cell.text) }}</em></span>
</div>
</template>
<script>

View file

@ -1,18 +1,18 @@
<template>
<div :class="classes">
<div :class="[prefixCls+ '-list']" v-el:hours>
<div :class="[prefixCls+ '-list']" ref="hours">
<ul :class="[prefixCls + '-ul']" @click="handleClickHours">
<li :class="getCellCls(item)" v-for="item in hoursList" v-show="!item.hide" :index="$index">{{ formatTime(item.text) }}</li>
<li :class="getCellCls(item)" v-for="(item, index) in hoursList" v-show="!item.hide" :index="index">{{ formatTime(item.text) }}</li>
</ul>
</div>
<div :class="[prefixCls+ '-list']" v-el:minutes>
<div :class="[prefixCls+ '-list']" ref="minutes">
<ul :class="[prefixCls + '-ul']" @click="handleClickMinutes">
<li :class="getCellCls(item)" v-for="item in minutesList" v-show="!item.hide" :index="$index">{{ formatTime(item.text) }}</li>
<li :class="getCellCls(item)" v-for="(item, index) in minutesList" v-show="!item.hide" :index="index">{{ formatTime(item.text) }}</li>
</ul>
</div>
<div :class="[prefixCls+ '-list']" v-show="showSeconds" v-el:seconds>
<div :class="[prefixCls+ '-list']" v-show="showSeconds" ref="seconds">
<ul :class="[prefixCls + '-ul']" @click="handleClickSeconds">
<li :class="getCellCls(item)" v-for="item in secondsList" v-show="!item.hide" :index="$index">{{ formatTime(item.text) }}</li>
<li :class="getCellCls(item)" v-for="(item, index) in secondsList" v-show="!item.hide" :index="index">{{ formatTime(item.text) }}</li>
</ul>
</div>
</div>
@ -159,9 +159,9 @@
this.$emit('on-pick-click');
},
scroll (type, index) {
const from = this.$els[type].scrollTop;
const from = this.$refs[type].scrollTop;
const to = 24 * this.getScrollIndex(type, index);
scrollTop(this.$els[type], from, to, 500);
scrollTop(this.$refs[type], from, to, 500);
},
getScrollIndex (type, index) {
const Type = firstUpperCase(type);
@ -177,7 +177,7 @@
const times = ['hours', 'minutes', 'seconds'];
this.$nextTick(() => {
times.forEach(type => {
this.$els[type].scrollTop = 24 * this.getScrollIndex(type, this[type]);
this.$refs[type].scrollTop = 24 * this.getScrollIndex(type, this[type]);
});
});
},
@ -199,7 +199,7 @@
this.scroll('seconds', val);
}
},
compiled () {
mounted () {
this.updateScroll();
this.$nextTick(() => this.compiled = true);
}

View file

@ -1,6 +1,6 @@
<template>
<div :class="classes" @click="handleClick">
<span :class="getCellCls(cell)" v-for="cell in cells"><em :index="$index">{{ cell.text }}</em></span>
<span :class="getCellCls(cell)" v-for="(cell, index) in cells"><em :index="index">{{ cell.text }}</em></span>
</div>
</template>
<script>

View file

@ -42,7 +42,7 @@
@on-pick="handleRangePick"
@on-pick-click="handlePickClick"></date-table>
<year-table
v-ref:left-year-table
ref="leftYearTable"
v-show="leftCurrentView === 'year'"
:year="leftTableYear"
:date="leftTableDate"
@ -51,7 +51,7 @@
@on-pick="handleLeftYearPick"
@on-pick-click="handlePickClick"></year-table>
<month-table
v-ref:left-month-table
ref="leftMonthTable"
v-show="leftCurrentView === 'month'"
:month="leftMonth"
:date="leftTableDate"
@ -95,7 +95,7 @@
@on-pick="handleRangePick"
@on-pick-click="handlePickClick"></date-table>
<year-table
v-ref:right-year-table
ref="rightYearTable"
v-show="rightCurrentView === 'year'"
:year="rightTableYear"
:date="rightTableDate"
@ -104,7 +104,7 @@
@on-pick="handleRightYearPick"
@on-pick-click="handlePickClick"></year-table>
<month-table
v-ref:right-month-table
ref="rightMonthTable"
v-show="rightCurrentView === 'month'"
:month="rightMonth"
:date="rightTableDate"
@ -115,7 +115,7 @@
</div>
<div :class="[prefixCls + '-content']" v-show="isTime">
<time-picker
v-ref:time-picker
ref="timePicker"
v-show="isTime"
@on-pick="handleTimePick"
@on-pick-click="handlePickClick"></time-picker>
@ -407,7 +407,7 @@
this.handleConfirm(false);
}
},
compiled () {
mounted () {
if (this.showTime) {
// todo
this.$refs.timePicker.date = this.minDate;

View file

@ -42,7 +42,7 @@
@on-pick="handleDatePick"
@on-pick-click="handlePickClick"></date-table>
<year-table
v-ref:year-table
ref="yearTable"
v-show="currentView === 'year'"
:year="year"
:date="date"
@ -51,7 +51,7 @@
@on-pick="handleYearPick"
@on-pick-click="handlePickClick"></year-table>
<month-table
v-ref:month-table
ref="monthTable"
v-show="currentView === 'month'"
:month="month"
:date="date"
@ -60,7 +60,7 @@
@on-pick="handleMonthPick"
@on-pick-click="handlePickClick"></month-table>
<time-picker
v-ref:time-picker
ref="timePicker"
show-date
v-show="currentView === 'time'"
@on-pick="handleTimePick"
@ -272,7 +272,7 @@
this.handleDatePick(date);
}
},
compiled () {
mounted () {
if (this.selectionMode === 'month') {
this.currentView = 'month';
}

View file

@ -7,7 +7,7 @@
<template v-else>{{ t('i.datepicker.startTime') }}</template>
</div>
<time-spinner
v-ref:time-spinner
ref="timeSpinner"
:show-seconds="showSeconds"
:hours="hours"
:minutes="minutes"
@ -25,7 +25,7 @@
<template v-else>{{ t('i.datepicker.endTime') }}</template>
</div>
<time-spinner
v-ref:time-spinner-end
ref="timeSpinnerEnd"
:show-seconds="showSeconds"
:hours="hoursEnd"
:minutes="minutesEnd"
@ -200,7 +200,7 @@
this.$refs.timeSpinnerEnd.updateScroll();
}
},
compiled () {
mounted () {
if (this.$parent && this.$parent.$options.name === 'DatePicker') this.showDate = true;
}
};

View file

@ -4,7 +4,7 @@
<div :class="[timePrefixCls + '-header']" v-if="showDate">{{ visibleDate }}</div>
<div :class="[prefixCls + '-content']">
<time-spinner
v-ref:time-spinner
ref="timeSpinner"
:show-seconds="showSeconds"
:hours="hours"
:minutes="minutes"
@ -108,7 +108,7 @@
this.$refs.timeSpinner.updateScroll();
}
},
compiled () {
mounted () {
if (this.$parent && this.$parent.$options.name === 'DatePicker') this.showDate = true;
}
};

View file

@ -2,7 +2,7 @@
<div
:class="[prefixCls]"
v-clickoutside="handleClose">
<div v-el:reference :class="[prefixCls + '-rel']">
<div ref="reference" :class="[prefixCls + '-rel']">
<slot>
<i-input
:class="[prefixCls + '-editor']"
@ -11,17 +11,19 @@
:size="size"
:placeholder="placeholder"
:value="visualValue"
@on-change="handleInputChange"
@on-input-change="handleInputChange"
@on-focus="handleFocus"
@on-click="handleIconClick"
@mouseenter="handleInputMouseenter"
@mouseleave="handleInputMouseleave"
@mouseenter.native="handleInputMouseenter"
@mouseleave.native="handleInputMouseleave"
:icon="iconType"></i-input>
</slot>
</div>
<Drop v-show="opened" :placement="placement" :transition="transition" v-ref:drop>
<div v-el:picker></div>
<transition :name="transition">
<Drop v-show="opened" :placement="placement" ref="drop">
<div ref="picker"></div>
</Drop>
</transition>
</div>
</template>
<script>
@ -192,7 +194,8 @@
visible: false,
picker: null,
internalValue: '',
disableClickOutSide: false // fixed when click a date,trigger clickoutside to close picker
disableClickOutSide: false, // fixed when click a date,trigger clickoutside to close picker
currentValue: this.value
};
},
computed: {
@ -358,21 +361,23 @@
handleClear () {
this.visible = false;
this.internalValue = '';
this.value = '';
this.currentValue = '';
this.$emit('on-clear');
this.$dispatch('on-form-change', '');
// todo
// this.$dispatch('on-form-change', '');
},
showPicker () {
if (!this.picker) {
let isConfirm = this.confirm;
const type = this.type;
this.picker = new Vue(this.panel).$mount(this.$els.picker);
this.picker = new Vue(this.panel).$mount(this.$refs.picker);
if (type === 'datetime' || type === 'datetimerange') {
this.confirm = true;
isConfirm = true;
this.picker.showTime = true;
}
this.picker.value = this.internalValue;
this.picker.confirm = this.confirm;
this.picker.confirm = isConfirm;
this.picker.selectionMode = this.selectionMode;
if (this.format) this.picker.format = this.format;
@ -388,8 +393,8 @@
}
this.picker.$on('on-pick', (date, visible = false) => {
if (!this.confirm) this.visible = visible;
this.value = date;
if (!isConfirm) this.visible = visible;
this.currentValue = date;
this.picker.value = date;
this.picker.resetView && this.picker.resetView();
this.emitChange(date);
@ -425,7 +430,8 @@
}
this.$emit('on-change', newDate);
this.$dispatch('on-form-change', newDate);
// todo
// this.$dispatch('on-form-change', newDate);
}
},
watch: {
@ -444,8 +450,12 @@
if (!val && this.picker && typeof this.picker.handleClear === 'function') {
this.picker.handleClear();
}
this.$emit('input', val);
},
value: {
value (val) {
this.currentValue = val;
},
currentValue: {
immediate: true,
handler (val) {
const type = this.type;
@ -462,6 +472,7 @@
}
this.internalValue = val;
this.$emit('input', val);
}
},
open (val) {
@ -478,16 +489,17 @@
this.picker.$destroy();
}
},
ready () {
mounted () {
if (this.open !== null) this.visible = this.open;
},
events: {
'on-form-blur' () {
return false;
},
'on-form-change' () {
return false;
}
}
// todo
// events: {
// 'on-form-blur' () {
// return false;
// },
// 'on-form-change' () {
// return false;
// }
// }
};
</script>

View file

@ -23,11 +23,11 @@ export default {
value: {}
},
created () {
if (!this.value) {
if (!this.currentValue) {
if (this.type === 'daterange' || this.type === 'datetimerange') {
this.value = ['',''];
this.currentValue = ['',''];
} else {
this.value = '';
this.currentValue = '';
}
}

View file

@ -24,11 +24,11 @@ export default {
value: {}
},
created () {
if (!this.value) {
if (!this.currentValue) {
if (this.type === 'timerange') {
this.value = ['',''];
this.currentValue = ['',''];
} else {
this.value = '';
this.currentValue = '';
}
}
this.panel = getPanel(this.type);

View file

@ -19,7 +19,8 @@
@keyup.enter="handleEnter"
@focus="handleFocus"
@blur="handleBlur"
@input="handleInput">
@input="handleInput"
@change="handleChange">
<div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady" ref="append"><slot name="append"></slot></div>
</template>
<textarea
@ -158,6 +159,9 @@
this.setCurrentValue(value);
this.$emit('on-change', event);
},
handleChange (event) {
this.$emit('on-input-change', event);
},
setCurrentValue (value) {
if (value === this.currentValue) return;
this.$nextTick(() => {

View file

@ -13,7 +13,7 @@ import Cascader from './components/cascader';
import Checkbox from './components/checkbox';
import Circle from './components/circle';
import Collapse from './components/collapse';
// import DatePicker from './components/date-picker';
import DatePicker from './components/date-picker';
import Dropdown from './components/dropdown';
// import Form from './components/form';
import Icon from './components/icon';
@ -37,7 +37,7 @@ import Switch from './components/switch';
import Tabs from './components/tabs';
import Tag from './components/tag';
import Timeline from './components/timeline';
// import TimePicker from './components/time-picker';
import TimePicker from './components/time-picker';
import Tooltip from './components/tooltip';
import Transfer from './components/transfer';
import Tree from './components/tree';
@ -63,7 +63,7 @@ const iview = {
Checkbox,
CheckboxGroup: Checkbox.Group,
iCircle: Circle,
// DatePicker,
DatePicker,
Dropdown,
DropdownItem: Dropdown.Item,
DropdownMenu: Dropdown.Menu,
@ -105,7 +105,7 @@ const iview = {
Tag,
Timeline,
TimelineItem: Timeline.Item,
// TimePicker,
TimePicker,
Tooltip,
Transfer,
Tree,