Commit c46f385a83c9bca751bed6a7d764d4a88dee3573

Authored by 梁灏
1 parent 10f622ac

update DatePicker

update DatePicker
src/components/date-picker/base/date-table.vue
... ... @@ -6,7 +6,7 @@
6 6 <div :class="[prefixCls + '-header']">
7 7 <span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>
8 8 </div>
9   - <span :class="getCellCls(cell)" v-for="cell in cells"><em>{{ cell.text }}</em></span>
  9 + <span :class="getCellCls(cell)" v-for="cell in cells"><em :index="$index">{{ cell.text }}</em></span>
10 10 </div>
11 11 </template>
12 12 <script>
... ... @@ -126,8 +126,40 @@
126 126 }
127 127 },
128 128 methods: {
129   - handleClick () {
  129 + handleClick (event) {
  130 + const target = event.target;
  131 + if (target.tagName === 'EM') {
  132 + const cell = this.cells[parseInt(event.target.getAttribute('index'))];
  133 + if (cell.disabled) return;
130 134  
  135 + let year = this.year;
  136 + let month = this.month;
  137 + let day = cell.text;
  138 +
  139 + if (cell.type === 'prev-month') {
  140 + if (month === 0) {
  141 + month = 11;
  142 + year--;
  143 + } else {
  144 + month--;
  145 + }
  146 + } else if (cell.type === 'next-month') {
  147 + if (month === 11) {
  148 + month = 0;
  149 + year++;
  150 + } else {
  151 + month++;
  152 + }
  153 + }
  154 +
  155 + const newDate = new Date(year, month, day);
  156 +
  157 + if (this.selectionMode === 'range') {
  158 + // todo
  159 + } else {
  160 + this.$emit('on-pick', newDate);
  161 + }
  162 + }
131 163 },
132 164 handleMouseMove () {
133 165  
... ...
src/components/date-picker/base/month-table.vue
1 1 <template>
2   - <div>month</div>
  2 + <div :class="classes" @click="handleClick">
  3 + <span :class="getCellCls(cell)" v-for="cell in cells"><em :index="$index">{{ cell.text }}月</em></span>
  4 + </div>
3 5 </template>
4 6 <script>
  7 + import { deepCopy } from '../../../utils/assist';
  8 + const prefixCls = 'ivu-date-picker-cells';
  9 +
5 10 export default {
6   -// props: {},
7   - data () {
8   - return {}
  11 + props: {
  12 + date: {},
  13 + month: {
  14 + type: Number
  15 + },
  16 + disabledDate: {}
9 17 },
10   - computed: {},
11   - methods: {}
  18 + computed: {
  19 + classes () {
  20 + return [
  21 + `${prefixCls}`,
  22 + `${prefixCls}-month`
  23 + ]
  24 + },
  25 + cells () {
  26 + let cells = [];
  27 + const cell_tmpl = {
  28 + text: '',
  29 + selected: false,
  30 + disabled: false
  31 + };
  32 +
  33 + for (let i = 0; i < 12; i++) {
  34 + const cell = deepCopy(cell_tmpl);
  35 + cell.text = i + 1;
  36 +
  37 + const date = new Date(this.date);
  38 + date.setMonth(i);
  39 + cell.disabled = typeof this.disabledDate === 'function' && this.disabledDate(date);
  40 +
  41 + cell.selected = Number(this.month) === i;
  42 + cells.push(cell);
  43 + }
  44 +
  45 + return cells;
  46 + }
  47 + },
  48 + methods: {
  49 + getCellCls (cell) {
  50 + return [
  51 + `${prefixCls}-cell`,
  52 + {
  53 + [`${prefixCls}-cell-selected`]: cell.selected,
  54 + [`${prefixCls}-cell-disabled`]: cell.disabled
  55 + }
  56 + ]
  57 + },
  58 + handleClick (event) {
  59 + const target = event.target;
  60 + if (target.tagName === 'EM') {
  61 + const index = parseInt(event.target.getAttribute('index'));
  62 + const cell = this.cells[index];
  63 + if (cell.disabled) return;
  64 +
  65 + this.$emit('on-pick', index);
  66 + }
  67 + }
  68 + }
12 69 }
13 70 </script>
14 71 \ No newline at end of file
... ...
src/components/date-picker/base/year-table.vue
1 1 <template>
2   - <div>year</div>
  2 + <div :class="classes" @click="handleClick">
  3 + <span :class="getCellCls(cell)" v-for="cell in cells"><em :index="$index">{{ cell.text }}</em></span>
  4 + </div>
3 5 </template>
4 6 <script>
  7 + import { deepCopy } from '../../../utils/assist';
  8 + const prefixCls = 'ivu-date-picker-cells';
  9 +
5 10 export default {
6   -// props: {},
7   - data () {
8   - return {}
  11 + props: {
  12 + date: {},
  13 + year: {},
  14 + disabledDate: {}
9 15 },
10   - computed: {},
11   - methods: {}
  16 + computed: {
  17 + classes () {
  18 + return [
  19 + `${prefixCls}`,
  20 + `${prefixCls}-year`
  21 + ]
  22 + },
  23 + startYear() {
  24 + return Math.floor(this.year / 10) * 10;
  25 + },
  26 + cells () {
  27 + let cells = [];
  28 + const cell_tmpl = {
  29 + text: '',
  30 + selected: false,
  31 + disabled: false
  32 + };
  33 +
  34 + for (let i = 0; i < 10; i++) {
  35 + const cell = deepCopy(cell_tmpl);
  36 + cell.text = this.startYear + i;
  37 +
  38 + const date = new Date(this.date);
  39 + date.setFullYear(cell.text);
  40 + cell.disabled = typeof this.disabledDate === 'function' && this.disabledDate(date);
  41 +
  42 + cell.selected = Number(this.year) === cell.text;
  43 + cells.push(cell);
  44 + }
  45 +
  46 + return cells;
  47 + }
  48 + },
  49 + methods: {
  50 + getCellCls (cell) {
  51 + return [
  52 + `${prefixCls}-cell`,
  53 + {
  54 + [`${prefixCls}-cell-selected`]: cell.selected,
  55 + [`${prefixCls}-cell-disabled`]: cell.disabled
  56 + }
  57 + ]
  58 + },
  59 + nextTenYear() {
  60 + this.$emit('on-pick', Number(this.year) + 10, false);
  61 + },
  62 + prevTenYear() {
  63 + this.$emit('on-pick', Number(this.year) - 10, false);
  64 + },
  65 + handleClick (event) {
  66 + const target = event.target;
  67 + if (target.tagName === 'EM') {
  68 + const cell = this.cells[parseInt(event.target.getAttribute('index'))];
  69 + if (cell.disabled) return;
  70 + this.$emit('on-pick', cell.text);
  71 + }
  72 + }
  73 + }
12 74 }
13 75 </script>
14 76 \ No newline at end of file
... ...
src/components/date-picker/panel/date.vue
... ... @@ -10,25 +10,25 @@
10 10 <div :class="[datePrefixCls + '-header']" v-show="currentView !== 'time'">
11 11 <span
12 12 :class="iconBtnCls('prev', '-double')"
13   - @click="prevYear"></span>
  13 + @click="prevYear"><Icon type="ios-arrow-left"></Icon></span>
14 14 <span
15 15 :class="iconBtnCls('prev')"
16 16 @click="prevMonth"
17   - v-show="currentView === 'date'"></span>
  17 + v-show="currentView === 'date'"><Icon type="ios-arrow-left"></Icon></span>
18 18 <span
19 19 :class="[datePrefixCls + '-header-label']"
20   - @click="showYearPicker">{{ }}</span>
  20 + @click="showYearPicker">{{ yearLabel }}</span>
21 21 <span
22 22 :class="[datePrefixCls + '-header-label']"
23 23 @click="showMonthPicker"
24   - v-show="currentView === 'date'">{{ }}</span>
  24 + v-show="currentView === 'date'">{{ month + 1 + '月' }}</span>
  25 + <span
  26 + :class="iconBtnCls('next', '-double')"
  27 + @click="nextYear"><Icon type="ios-arrow-right"></Icon></span>
25 28 <span
26 29 :class="iconBtnCls('next')"
27 30 @click="nextMonth"
28   - v-show="currentView === 'date'"></span>
29   - <span
30   - :class="iconBtnCls('next', '-double')"
31   - @click="nextYear"></span>
  31 + v-show="currentView === 'date'"><Icon type="ios-arrow-right"></Icon></span>
32 32 </div>
33 33 <div :class="[prefixCls + '-content']">
34 34 <date-table
... ... @@ -39,25 +39,38 @@
39 39 :value="value"
40 40 :week="week"
41 41 :selection-mode="selectionMode"
42   - :disabled-date="disabledDate"></date-table>
  42 + :disabled-date="disabledDate"
  43 + @on-pick="handleDatePick"></date-table>
43 44 <year-table
44   - v-show="currentView === 'year'"></year-table>
  45 + v-ref:year-table
  46 + v-show="currentView === 'year'"
  47 + :year="year"
  48 + :date="date"
  49 + :disabled-date="disabledDate"
  50 + @on-pick="handleYearPick"></year-table>
45 51 <month-table
46   - v-show="currentView === 'month'"></month-table>
  52 + v-ref:month-table
  53 + v-show="currentView === 'month'"
  54 + :month="month"
  55 + :date="date"
  56 + :disabled-date="disabledDate"
  57 + @on-pick="handleMonthPick"></month-table>
47 58 </div>
48 59 </div>
49 60 </div>
50 61 </template>
51 62 <script>
  63 + import Icon from '../../icon/icon.vue';
52 64 import DateTable from '../base/date-table.vue';
53 65 import YearTable from '../base/year-table.vue';
54 66 import MonthTable from '../base/month-table.vue';
  67 + import { formatDate, parseDate } from '../util';
55 68  
56 69 const prefixCls = 'ivu-picker-panel';
57 70 const datePrefixCls = 'ivu-date-picker';
58 71  
59 72 export default {
60   - components: { DateTable, YearTable, MonthTable },
  73 + components: { Icon, DateTable, YearTable, MonthTable },
61 74 data () {
62 75 return {
63 76 prefixCls: prefixCls,
... ... @@ -78,10 +91,20 @@
78 91 }
79 92 },
80 93 computed: {
81   -
  94 + yearLabel () {
  95 + const year = this.year;
  96 + if (!year) return '';
  97 + if (this.currentView === 'year') {
  98 + const startYear = Math.floor(year / 10) * 10;
  99 + return `${startYear}年 - ${startYear + 9}年`;
  100 + }
  101 + return `${year}年`
  102 + }
82 103 },
83 104 watch: {
84 105 value (newVal) {
  106 + console.log(12331)
  107 + if (!newVal) return;
85 108 newVal = new Date(newVal);
86 109 if (!isNaN(newVal)) {
87 110 // todo
... ... @@ -95,6 +118,10 @@
95 118 }
96 119 },
97 120 methods: {
  121 + handleClear() {
  122 + this.date = new Date();
  123 + this.$emit('on-pick', '');
  124 + },
98 125 handleShortcutClick (shortcut) {
99 126  
100 127 },
... ... @@ -105,23 +132,98 @@
105 132 `${datePrefixCls}-${direction}-btn-arrow${type}`,
106 133 ]
107 134 },
  135 + resetDate () {
  136 + this.date = new Date(this.date);
  137 + },
108 138 prevYear () {
109   -
  139 + if (this.currentView === 'year') {
  140 + this.$refs.yearTable.prevTenYear();
  141 + } else {
  142 + this.year--;
  143 + this.date.setFullYear(this.year);
  144 + this.resetDate();
  145 + }
110 146 },
111 147 nextYear () {
112   -
  148 + if (this.currentView === 'year') {
  149 + this.$refs.yearTable.nextTenYear();
  150 + } else {
  151 + this.year++;
  152 + this.date.setFullYear(this.year);
  153 + this.resetDate();
  154 + }
113 155 },
114 156 prevMonth () {
115   -
  157 + this.month--;
  158 + if (this.month < 0) {
  159 + this.month = 11;
  160 + this.year--;
  161 + }
116 162 },
117 163 nextMonth () {
118   -
  164 + this.month++;
  165 + if (this.month > 11) {
  166 + this.month = 0;
  167 + this.year++;
  168 + }
119 169 },
120 170 showYearPicker () {
121   -
  171 + this.currentView = 'year';
122 172 },
123 173 showMonthPicker () {
  174 + this.currentView = 'month';
  175 + },
  176 + handleYearPick(year, close = true) {
  177 + this.year = year;
  178 + if (!close) return;
124 179  
  180 + this.date.setFullYear(year);
  181 + if (this.selectionMode === 'year') {
  182 + this.$emit('on-pick', new Date(year));
  183 + } else {
  184 + this.currentView = 'month';
  185 + }
  186 +
  187 + this.resetDate();
  188 + },
  189 + handleMonthPick (month) {
  190 + this.month = month;
  191 + const selectionMode = this.selectionMode;
  192 + if (selectionMode !== 'month') {
  193 + this.date.setMonth(month);
  194 + this.currentView = 'date';
  195 + this.resetDate();
  196 + } else {
  197 + this.date.setMonth(month);
  198 + this.year && this.date.setFullYear(this.year);
  199 + this.resetDate();
  200 + const value = new Date(this.date.getFullYear(), month, 1);
  201 + this.$emit('on-pick', value);
  202 + }
  203 + },
  204 + handleDatePick (value) {
  205 + if (this.selectionMode === 'day') {
  206 + if (!this.showTime) {
  207 + this.$emit('on-pick', new Date(value.getTime()));
  208 + }
  209 + this.date.setFullYear(value.getFullYear());
  210 + this.date.setMonth(value.getMonth());
  211 + this.date.setDate(value.getDate());
  212 + }
  213 +
  214 + this.resetDate();
  215 + },
  216 + resetView() {
  217 + if (this.selectionMode === 'month') {
  218 + this.currentView = 'month';
  219 + } else if (this.selectionMode === 'year') {
  220 + this.currentView = 'year';
  221 + } else {
  222 + this.currentView = 'date';
  223 + }
  224 +
  225 + this.year = this.date.getFullYear();
  226 + this.month = this.date.getMonth();
125 227 }
126 228 },
127 229 compiled () {
... ... @@ -133,9 +235,6 @@
133 235 this.year = this.date.getFullYear();
134 236 this.month = this.date.getMonth();
135 237 }
136   - },
137   - beforeDestroy () {
138   -
139 238 }
140 239 }
141 240 </script>
142 241 \ No newline at end of file
... ...
src/components/date-picker/picker.vue
1 1 <template>
2 2 <div
3 3 :class="[prefixCls]"
4   - v-clickoutside="handleClose"
5   - @mouseenter="handleMouseenter"
6   - @mouseleave="handleMouseleave">
  4 + v-clickoutside="handleClose">
7 5 <i-input
8 6 v-el:reference
9 7 :class="[prefixCls + '-editor']"
... ... @@ -11,10 +9,13 @@
11 9 :disabled="disabled"
12 10 :size="size"
13 11 :placeholder="placeholder"
14   - :value.sync="visualValue"
  12 + :value="visualValue"
  13 + @on-change="handleInputChange"
15 14 @on-focus="handleFocus"
16 15 @on-blur="handleBlur"
17 16 @on-click="handleIconClick"
  17 + @mouseenter="handleInputMouseenter"
  18 + @mouseleave="handleInputMouseleave"
18 19 :icon="iconType"></i-input>
19 20 <Drop v-show="visible" :placement="placement" transition="slide-up" v-ref:drop>
20 21 <div v-el:picker></div>
... ... @@ -27,13 +28,14 @@
27 28 import Drop from '../../components/select/dropdown.vue';
28 29 import clickoutside from '../../directives/clickoutside';
29 30 import { oneOf } from '../../utils/assist';
30   - import { formatDate } from './util';
  31 + import { formatDate, parseDate } from './util';
31 32  
32 33 const prefixCls = 'ivu-date-picker';
33 34  
34 35 const DEFAULT_FORMATS = {
35 36 date: 'yyyy-MM-dd',
36 37 month: 'yyyy-MM',
  38 + year: 'yyyy',
37 39 datetime: 'yyyy-MM-dd HH:mm:ss',
38 40 time: 'HH:mm:ss',
39 41 timerange: 'HH:mm:ss',
... ... @@ -41,6 +43,96 @@
41 43 datetimerange: 'yyyy-MM-dd HH:mm:ss'
42 44 };
43 45  
  46 + const RANGE_SEPARATOR = ' - ';
  47 +
  48 + const DATE_FORMATTER = function(value, format) {
  49 + return formatDate(value, format);
  50 + };
  51 + const DATE_PARSER = function(text, format) {
  52 + return parseDate(text, format);
  53 + };
  54 + const RANGE_FORMATTER = function(value, format) {
  55 + if (Array.isArray(value) && value.length === 2) {
  56 + const start = value[0];
  57 + const end = value[1];
  58 +
  59 + if (start && end) {
  60 + return formatDate(start, format) + RANGE_SEPARATOR + formatDate(end, format);
  61 + }
  62 + }
  63 + return '';
  64 + };
  65 + const RANGE_PARSER = function(text, format) {
  66 + const array = text.split(RANGE_SEPARATOR);
  67 + if (array.length === 2) {
  68 + const range1 = array[0];
  69 + const range2 = array[1];
  70 +
  71 + return [parseDate(range1, format), parseDate(range2, format)];
  72 + }
  73 + return [];
  74 + };
  75 +
  76 + const TYPE_VALUE_RESOLVER_MAP = {
  77 + default: {
  78 + formatter(value) {
  79 + if (!value) return '';
  80 + return '' + value;
  81 + },
  82 + parser(text) {
  83 + if (text === undefined || text === '') return null;
  84 + return text;
  85 + }
  86 + },
  87 + date: {
  88 + formatter: DATE_FORMATTER,
  89 + parser: DATE_PARSER
  90 + },
  91 + datetime: {
  92 + formatter: DATE_FORMATTER,
  93 + parser: DATE_PARSER
  94 + },
  95 + daterange: {
  96 + formatter: RANGE_FORMATTER,
  97 + parser: RANGE_PARSER
  98 + },
  99 + datetimerange: {
  100 + formatter: RANGE_FORMATTER,
  101 + parser: RANGE_PARSER
  102 + },
  103 + timerange: {
  104 + formatter: RANGE_FORMATTER,
  105 + parser: RANGE_PARSER
  106 + },
  107 + time: {
  108 + formatter: DATE_FORMATTER,
  109 + parser: DATE_PARSER
  110 + },
  111 + month: {
  112 + formatter: DATE_FORMATTER,
  113 + parser: DATE_PARSER
  114 + },
  115 + year: {
  116 + formatter: DATE_FORMATTER,
  117 + parser: DATE_PARSER
  118 + },
  119 + number: {
  120 + formatter(value) {
  121 + if (!value) return '';
  122 + return '' + value;
  123 + },
  124 + parser(text) {
  125 + let result = Number(text);
  126 +
  127 + if (!isNaN(text)) {
  128 + return result;
  129 + } else {
  130 + return null;
  131 + }
  132 + }
  133 + }
  134 + };
  135 +
44 136 const PLACEMENT_MAP = {
45 137 left: 'bottom-start',
46 138 center: 'bottom-center',
... ... @@ -101,6 +193,47 @@
101 193 },
102 194 placement () {
103 195 return PLACEMENT_MAP[this.align];
  196 + },
  197 + selectionMode() {
  198 + if (this.type === 'week') {
  199 + return 'week';
  200 + } else if (this.type === 'month') {
  201 + return 'month';
  202 + } else if (this.type === 'year') {
  203 + return 'year';
  204 + }
  205 +
  206 + return 'day';
  207 + },
  208 + visualValue: {
  209 + get () {
  210 + const value = this.internalValue;
  211 + if (!value) return;
  212 + const formatter = (
  213 + TYPE_VALUE_RESOLVER_MAP[this.type] ||
  214 + TYPE_VALUE_RESOLVER_MAP['default']
  215 + ).formatter;
  216 + const format = DEFAULT_FORMATS[this.type];
  217 +
  218 + return formatter(value, this.format || format);
  219 + },
  220 +
  221 + set (value) {
  222 + if (value) {
  223 + const type = this.type;
  224 + const parser = (
  225 + TYPE_VALUE_RESOLVER_MAP[type] ||
  226 + TYPE_VALUE_RESOLVER_MAP['default']
  227 + ).parser;
  228 + const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);
  229 +
  230 + if (parsedValue) {
  231 + if (this.picker) this.picker.value = parsedValue;
  232 + }
  233 + return;
  234 + }
  235 + if (this.picker) this.picker.value = value;
  236 + }
104 237 }
105 238 },
106 239 methods: {
... ... @@ -113,29 +246,51 @@
113 246 handleBlur () {
114 247  
115 248 },
116   - handleMouseenter () {
  249 + handleInputChange (val) {
  250 + this.visualValue = val;
  251 + },
  252 + handleInputMouseenter () {
117 253 if (this.readonly || this.disabled) return;
118 254 if (this.visualValue) {
119 255 this.showClose = true;
120 256 }
121 257 },
122   - handleMouseleave () {
  258 + handleInputMouseleave () {
123 259 this.showClose = false;
124 260 },
125 261 handleIconClick () {
126   -
  262 + if (!this.showClose) return;
  263 + this.visible = false;
  264 + this.internalValue = '';
  265 + this.value = '';
127 266 },
128 267 showPicker () {
129 268 if (!this.picker) {
130 269 this.picker = new Vue(this.panel).$mount(this.$els.picker);
131 270 this.picker.value = this.internalValue;
  271 + this.picker.selectionMode = this.selectionMode;
132 272 if (this.format) this.picker.format = this.format;
133 273  
134 274 const options = this.options;
135 275 for (const option in options) {
136 276 this.picker[option] = options[option];
137 277 }
  278 +
  279 + this.picker.$on('on-pick', (date, visible = false) => {
  280 + this.$emit('on-change', date);
  281 + this.value = date;
  282 + this.visible = visible;
  283 + this.picker.resetView && this.picker.resetView();
  284 + });
  285 +
  286 + // todo $on('on-range')
138 287 }
  288 + if (this.internalValue instanceof Date) {
  289 + this.picker.date = new Date(this.internalValue.getTime());
  290 + } else {
  291 + this.picker.value = this.internalValue;
  292 + }
  293 + this.picker.resetView && this.picker.resetView();
139 294 }
140 295 },
141 296 watch: {
... ... @@ -143,14 +298,24 @@
143 298 if (val) {
144 299 this.showPicker();
145 300 this.$refs.drop.update();
  301 + this.$emit('on-open-change', true);
146 302 } else {
  303 + if (this.picker) {
  304 + this.picker.resetView && this.picker.resetView();
  305 + }
147 306 this.$refs.drop.destroy();
  307 + this.$emit('on-open-change', false);
  308 + }
  309 + },
  310 + internalValue(val) {
  311 + if (!val && this.picker && typeof this.picker.handleClear === 'function') {
  312 + this.picker.handleClear();
148 313 }
149 314 },
150 315 value: {
151 316 immediate: true,
152 317 handler (val) {
153   - this.internalValue = formatDate(val);
  318 + this.internalValue = val;
154 319 }
155 320 }
156 321 },
... ...
src/components/date-picker/picker/date-picker.js
... ... @@ -20,9 +20,7 @@ export default {
20 20 },
21 21 default: 'date'
22 22 },
23   - value: {
24   - type: [String, Array]
25   - }
  23 + value: {}
26 24 },
27 25 created () {
28 26 if (!this.value) {
... ...
src/components/input/input.vue
... ... @@ -14,7 +14,8 @@
14 14 v-model="value"
15 15 @keyup.enter="handleEnter"
16 16 @focus="handleFocus"
17   - @blur="handleBlur">
  17 + @blur="handleBlur"
  18 + @change="handleChange">
18 19 <div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady" v-el:append><slot name="append"></slot></div>
19 20 </template>
20 21 <textarea
... ... @@ -31,7 +32,8 @@
31 32 v-model="value"
32 33 @keyup.enter="handleEnter"
33 34 @focus="handleFocus"
34   - @blur="handleBlur">
  35 + @blur="handleBlur"
  36 + @change="handleChange">
35 37 </textarea>
36 38 </div>
37 39 </template>
... ... @@ -52,7 +54,7 @@
52 54 value: {
53 55 type: [String, Number],
54 56 default: '',
55   - twoWay: true
  57 +// twoWay: true
56 58 },
57 59 size: {
58 60 validator (value) {
... ... @@ -139,6 +141,9 @@
139 141 handleBlur () {
140 142 this.$emit('on-blur');
141 143 },
  144 + handleChange () {
  145 + this.$emit('on-change', this.value);
  146 + },
142 147 resizeTextarea () {
143 148 const autosize = this.autosize;
144 149 if (!autosize || this.type !== 'textarea') {
... ... @@ -152,11 +157,10 @@
152 157 }
153 158 },
154 159 watch: {
155   - value (val) {
  160 + value () {
156 161 this.$nextTick(() => {
157 162 this.resizeTextarea();
158 163 });
159   - this.$emit('on-change', val);
160 164 }
161 165 },
162 166 ready () {
... ...
src/styles/components/date-picker.less
1 1 @date-picker-prefix-cls: ~"@{css-prefix}date-picker";
  2 +@picker-prefix-cls: ~"@{css-prefix}picker";
2 3  
3 4 .@{date-picker-prefix-cls} {
4 5 position: relative;
5 6 .@{select-dropdown-prefix-cls} {
6 7 width: auto;
  8 + padding: 0;
7 9 overflow: visible;
8 10 max-height: none;
9 11 }
... ... @@ -100,4 +102,75 @@
100 102 }
101 103 }
102 104 }
  105 +
  106 + &-cells-year,&-cells-month{
  107 + margin-top: 14px;
  108 + span{
  109 + width: 40px;
  110 + height: 28px;
  111 + line-height: 28px;
  112 + margin: 10px 12px;
  113 + border-radius: @btn-border-radius-small;
  114 + em{
  115 + width: 40px;
  116 + height: 28px;
  117 + line-height: 28px;
  118 + margin: 0;
  119 + }
  120 + }
  121 + }
  122 +
  123 + &-header{
  124 + height: 32px;
  125 + line-height: 32px;
  126 + text-align: center;
  127 + border-bottom: 1px solid @border-color-split;
  128 + &-label{
  129 + cursor: pointer;
  130 + transition: color @transition-time @ease-in-out;
  131 + &:hover{
  132 + color: @primary-color;
  133 + }
  134 + }
  135 + }
  136 + &-prev-btn{
  137 + float: left;
  138 + &-arrow-double{
  139 + margin-left: 10px;
  140 + i:after{
  141 + content: "\F3D2";
  142 + }
  143 + }
  144 + }
  145 + &-next-btn{
  146 + float: right;
  147 + &-arrow-double{
  148 + margin-right: 10px;
  149 + i:after{
  150 + content: "\F3D3";
  151 + }
  152 + }
  153 + }
  154 +}
  155 +
  156 +.@{picker-prefix-cls} {
  157 + &-panel{
  158 + &-icon-btn{
  159 + display: inline-block;
  160 + width: 20px;
  161 + height: 24px;
  162 + line-height: 26px;
  163 + margin-top: 4px;
  164 + text-align: center;
  165 + cursor: pointer;
  166 + color: @btn-disable-color;
  167 + transition: color @transition-time @ease-in-out;
  168 + &:hover{
  169 + color: @primary-color;
  170 + }
  171 + i{
  172 + font-size: 14px;
  173 + }
  174 + }
  175 + }
103 176 }
104 177 \ No newline at end of file
... ...
test/routers/date.vue
1 1 <template>
2 2 <div style="margin: 50px">
3   - <date-picker style="width:200px" placeholder="请选择日期" :value.sync="value" :options="options"></date-picker>
  3 + <br>
  4 + <row>
  5 + <i-col span="4">
  6 + <date-picker style="width:200px" placeholder="请选择日期" :value.sync="value" :options="options" @on-change="change" @on-open-change="change2" :format="format"></date-picker>
  7 + </i-col>
  8 + <i-col span="4">
  9 + <date-picker type="year" style="width:200px" placeholder="请选择日期" :value.sync="value" :options="options"></date-picker>
  10 + </i-col>
  11 + <i-col span="4">
  12 + <date-picker type="month" style="width:200px" placeholder="请选择日期" :value.sync="value" :options="options"></date-picker>
  13 + </i-col>
  14 + </row>
4 15 </div>
5 16 </template>
6 17 <script>
7 18 export default {
8 19 data () {
9 20 return {
10   - value: '2016-12-18',
  21 + value: new Date(),
11 22 // value: '',
12 23 options: {
13 24 disabledDate(time) {
14 25 return time.getTime() < Date.now() - 8.64e7;
15 26 // return time && time.valueOf() < Date.now();
16 27 }
17   - }
  28 + },
  29 + format: 'yyyy/MM/dd'
18 30 }
19 31 },
20 32 computed: {},
21   - methods: {}
  33 + methods: {
  34 + change (date) {
  35 +// console.log(date)
  36 + },
  37 + change2 (s) {
  38 +// console.log(s)
  39 + }
  40 + }
22 41 }
23 42 </script>
24 43 \ No newline at end of file
... ...