2
0
mirror of https://github.com/tenrok/vue2-datepicker.git synced 2026-06-23 23:40:36 +03:00

Merge branch 'master' into master

This commit is contained in:
mengxiong
2017-10-17 21:03:47 +08:00
committed by GitHub
10 changed files with 257 additions and 59 deletions
+1
View File
@@ -2,3 +2,4 @@
node_modules/ node_modules/
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
package-lock.json
+33 -9
View File
@@ -25,6 +25,13 @@ export default {
return { return {
time1: '', time1: '',
time2: '', time2: '',
shortcuts: [
{
text: 'Today',
start: new Date(),
end: new Date()
}
]
} }
} }
} }
@@ -32,19 +39,36 @@ export default {
<template> <template>
<div> <div>
<date-picker v-model="time1"></date-picker> <date-picker v-model="time1" :first-day-of-week="1"></date-picker>
<date-picker v-model="time2" range></date-picker> <date-picker v-model="time2" range :shortcuts="shortcuts"></date-picker>
</div> </div>
</template> </template>
``` ```
## Attributes ## Attributes
| Prop | Type | Default | Description | | Prop | Type | Default | Description |
|-------------|---------------|------------|--------------------------------| |-------------------|---------------|-------------|---------------------------------------------------|
| range | Boolean | false | if true, the type is daterange | | range | Boolean | false | if true, the type is daterange |
| format | String | yyyy-MM-dd | Date formatting string | | format | String | yyyy-MM-dd | Date formatting string |
| lang | String | zh | Translation (en/zh/es/fr) | | lang | String | zh | Translation (en/zh/es/fs) |
| placeholder | String | | input placeholder text | | placeholder | String | | input placeholder text |
| width | String/Number | 210 | input size | | width | String/Number | 210 | input size |
| disabled-days | Array | [] | Days in YYYY-MM-DD format to disable |
| not-before | String | '' | Disable all dates before date in YYY-MM-DD format |
| not-after | String | '' | Disable all dates after date in YYY-MM-DD format |
| shortcuts | Boolean/Array | true | the shortcuts for the range picker |
| first-day-of-week | Number | 7 | set the first day of week (1-7) |
## shortcuts
* true - show the default shortcuts
* false - hide the shortcuts
* Object[] - custom shortcuts, [{text, start, end}]
| Prop | Type | Description |
|-----------------|---------------|------------------------|
| text | String | Text |
| start | Date | Start Date |
| end | Date | End Date |
+29 -20
View File
@@ -4,7 +4,7 @@
<a class="calendar__prev-icon" @click="changeYear(-1)">&laquo;</a> <a class="calendar__prev-icon" @click="changeYear(-1)">&laquo;</a>
<a v-show="currentPanel === 'date'" class="calendar__prev-icon" @click="changeMonth(-1)">&lsaquo;</a> <a v-show="currentPanel === 'date'" class="calendar__prev-icon" @click="changeMonth(-1)">&lsaquo;</a>
<a class="calendar__next-icon" @click="changeYear(1)">&raquo;</a> <a class="calendar__next-icon" @click="changeYear(1)">&raquo;</a>
<a v-show="currentPanel === 'date'" class="calendar__next-icon" @click="changeMonth(1)" >&rsaquo;</a> <a v-show="currentPanel === 'date'" class="calendar__next-icon" @click="changeMonth(1)">&rsaquo;</a>
<a @click="showMonths">{{months[currentMonth]}}</a> <a @click="showMonths">{{months[currentMonth]}}</a>
<a @click="showYears">{{currentYear}}</a> <a @click="showYears">{{currentYear}}</a>
</div> </div>
@@ -17,10 +17,7 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="row in dates"> <tr v-for="row in dates">
<td v-for="cell in row" <td v-for="cell in row" :title="cell.title" :class="getClasses(cell)" @click="selectDate(cell)">{{cell.day}}</td>
:title="cell.title"
:class="getClasses(cell)"
@click="selectDate(cell)">{{cell.day}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -45,7 +42,6 @@ export default {
data () { data () {
const translation = this.$parent.translation const translation = this.$parent.translation
return { return {
days: translation.days,
months: translation.months, months: translation.months,
dates: [], dates: [],
now: new Date(), // calendar-header 显示的时间, 用于切换日历 now: new Date(), // calendar-header 显示的时间, 用于切换日历
@@ -54,6 +50,11 @@ export default {
} }
}, },
computed: { computed: {
days () {
const days = this.$parent.translation.days
const firstday = +this.$parent.firstDayOfWeek
return days.concat(days).slice(firstday, firstday + 7)
},
currentYear () { currentYear () {
return this.now.getFullYear() return this.now.getFullYear()
}, },
@@ -88,7 +89,7 @@ export default {
function getCalendar (time, firstday, length, classes) { function getCalendar (time, firstday, length, classes) {
return Array.apply(null, { length }).map((v, i) => { // eslint-disable-line return Array.apply(null, { length }).map((v, i) => { // eslint-disable-line
let day = firstday + i let day = firstday + i
const date = new Date(time.getFullYear(), time.getMonth(), day) const date = new Date(time.getFullYear(), time.getMonth(), day, 0, 0, 0)
return { return {
title: date.toLocaleDateString(), title: date.toLocaleDateString(),
date, date,
@@ -97,9 +98,10 @@ export default {
} }
}) })
} }
const firstDayOfWeek = this.$parent.firstDayOfWeek
const time = new Date(this.now) const time = new Date(this.now)
time.setDate(0) // 把时间切换到上个月最后一天 time.setDate(0) // 把时间切换到上个月最后一天
const lastMonthLength = time.getDay() + 1 // time.getDay() 0是星期天, 1是星期一 ... const lastMonthLength = (time.getDay() + 7 - firstDayOfWeek) % 7 + 1 // time.getDay() 0是星期天, 1是星期一 ...
const lastMonthfirst = time.getDate() - (lastMonthLength - 1) const lastMonthfirst = time.getDate() - (lastMonthLength - 1)
const lastMonth = getCalendar(time, lastMonthfirst, lastMonthLength, 'lastMonth') const lastMonth = getCalendar(time, lastMonthfirst, lastMonthLength, 'lastMonth')
@@ -129,11 +131,18 @@ export default {
const endTime = this.endAt ? new Date(this.endAt).setHours(0, 0, 0, 0) : 0 const endTime = this.endAt ? new Date(this.endAt).setHours(0, 0, 0, 0) : 0
const today = new Date().setHours(0, 0, 0, 0) const today = new Date().setHours(0, 0, 0, 0)
if (this.$parent.disabledDays.some(v => +new Date(v) === +cell.date) ||
(this.$parent.notBefore !== '' && cell.date.getTime() < (new Date(this.$parent.notBefore)).getTime()) ||
(this.$parent.notAfter !== '' && cell.date.getTime() > (new Date(this.$parent.notAfter)).getTime())) {
return 'disabled'
}
classes.push(cell.classes) classes.push(cell.classes)
if (cellTime === today) { if (cellTime === today) {
classes.push('today') classes.push('today')
} }
// range classes // range classes
if (cellTime === curTime) { if (cellTime === curTime) {
classes.push('current') classes.push('current')
@@ -210,11 +219,9 @@ export default {
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
.calendar { .calendar {
float: left; float: left;
padding: 6px 12px; padding: 6px 12px;
@@ -240,7 +247,8 @@ export default {
font-size: 20px; font-size: 20px;
padding: 0 6px; padding: 0 6px;
} }
.calendar-header > a:hover {
.calendar-header>a:hover {
color: #1284e7; color: #1284e7;
} }
@@ -273,14 +281,14 @@ export default {
.calendar-table td.inrange, .calendar-table td.inrange,
.calendar-table td:hover, .calendar-table td:hover,
.calendar-year > a:hover, .calendar-year>a:hover,
.calendar-month > a:hover { .calendar-month>a:hover {
background-color: #eaf8fe; background-color: #eaf8fe;
} }
.calendar-table td.current, .calendar-table td.current,
.calendar-year > a.current, .calendar-year>a.current,
.calendar-month > a.current { .calendar-month>a.current {
color: #fff; color: #fff;
background-color: #1284e7; background-color: #1284e7;
} }
@@ -300,24 +308,25 @@ export default {
color: #20a0ff; color: #20a0ff;
} }
.calendar-year,.calendar-month { .calendar-year,
.calendar-month {
width: 100%; width: 100%;
height: 224px; height: 224px;
padding: 7px 0; padding: 7px 0;
text-align: center; text-align: center;
} }
.calendar-year > a {
.calendar-year>a {
display: inline-block; display: inline-block;
width: 40%; width: 40%;
margin: 1px 5%; margin: 1px 5%;
line-height: 40px; line-height: 40px;
} }
.calendar-month > a {
.calendar-month>a {
display: inline-block; display: inline-block;
width: 30%; width: 30%;
line-height: 40px; line-height: 40px;
margin: 8px 1.5%; margin: 8px 1.5%;
} }
</style> </style>
+60 -29
View File
@@ -20,14 +20,22 @@
ref="calendar" ref="calendar"
v-show="showPopup"> v-show="showPopup">
<template v-if="!range"> <template v-if="!range">
<calendar-panel @select="showPopup = false" v-model="currentValue" :show="showPopup"></calendar-panel> <calendar-panel @select="showPopup = false"
v-model="currentValue"
:show="showPopup"></calendar-panel>
</template> </template>
<template v-else> <template v-else>
<div class="datepicker-top"> <div class="datepicker-top" v-if="ranges.length">
<span v-for="range in ranges" @click="selectRange(range)">{{range.text}}</span> <span v-for="range in ranges" @click="selectRange(range)">{{range.text}}</span>
</div> </div>
<calendar-panel style="width:50%;box-shadow:1px 0 rgba(0, 0, 0, .1)" v-model="currentValue[0]" :end-at="currentValue[1]" :show="showPopup"></calendar-panel> <calendar-panel style="width:50%;box-shadow:1px 0 rgba(0, 0, 0, .1)"
<calendar-panel style="width:50%;" v-model="currentValue[1]" :start-at="currentValue[0]" :show="showPopup"></calendar-panel> v-model="currentValue[0]"
:end-at="currentValue[1]"
:show="showPopup"></calendar-panel>
<calendar-panel style="width:50%;"
v-model="currentValue[1]"
:start-at="currentValue[0]"
:show="showPopup"></calendar-panel>
</template> </template>
</div> </div>
</div> </div>
@@ -57,7 +65,28 @@ export default {
type: String, type: String,
default: 'zh' default: 'zh'
}, },
value: null value: null,
shortcuts: {
type: [Boolean, Array],
default: true
},
disabledDays: {
type: Array,
default: function () { return [] }
},
notBefore: {
type: String,
default: ''
},
notAfter: {
type: String,
default: ''
},
firstDayOfWeek: {
default: 7,
type: Number,
validator: val => val >= 1 && val <= 7
}
}, },
data () { data () {
return { return {
@@ -87,7 +116,6 @@ export default {
showPopup (val) { showPopup (val) {
if (val) { if (val) {
this.$nextTick(this.displayPopup) this.$nextTick(this.displayPopup)
// this.displayPopup()
} }
} }
}, },
@@ -109,9 +137,6 @@ export default {
} }
}, },
methods: { methods: {
selectDate (date) {
},
closePopup () { closePopup () {
this.showPopup = false this.showPopup = false
}, },
@@ -176,26 +201,32 @@ export default {
this.$emit('input', [range.start, range.end]) this.$emit('input', [range.start, range.end])
}, },
initRanges () { initRanges () {
this.ranges = [{ if (Array.isArray(this.shortcuts)) {
text: '未来7天', this.ranges = this.shortcuts
start: new Date(), } else if (this.shortcuts) {
end: new Date(Date.now() + 3600 * 1000 * 24 * 7) this.ranges = [{
}, { text: '未来7天',
text: '未来30天', start: new Date(),
start: new Date(), end: new Date(Date.now() + 3600 * 1000 * 24 * 7)
end: new Date(Date.now() + 3600 * 1000 * 24 * 30) }, {
}, { text: '未来30天',
text: '最近7天', start: new Date(),
start: new Date(Date.now() - 3600 * 1000 * 24 * 7), end: new Date(Date.now() + 3600 * 1000 * 24 * 30)
end: new Date() }, {
}, { text: '最近7天',
text: '最近30天', start: new Date(Date.now() - 3600 * 1000 * 24 * 7),
start: new Date(Date.now() - 3600 * 1000 * 24 * 30), end: new Date()
end: new Date() }, {
}] text: '最近30天',
this.ranges.forEach((v, i) => { start: new Date(Date.now() - 3600 * 1000 * 24 * 30),
v.text = this.translation.pickers[i] end: new Date()
}) }]
this.ranges.forEach((v, i) => {
v.text = this.translation.pickers[i]
})
} else {
this.ranges = []
}
}, },
displayPopup () { displayPopup () {
const dw = document.documentElement.clientWidth const dw = document.documentElement.clientWidth
+38
View File
@@ -0,0 +1,38 @@
<template>
<div id="app">
<div class="demo">
<span class="label">default:</span>
<date-picker v-model="value1" lang="en" :first-day-of-week="1"></date-picker>
</div>
<div class="demo">
<span class="label">range:</span>
<date-picker v-model="value2" range lang="zh" :disabled-days="disabledDays"></date-picker>
</div>
</div>
</template>
<script>
import DatePicker from '../datepicker/index.vue'
export default {
name: 'app',
components: { DatePicker },
data () {
return {
value1: new Date(),
disabledDays: ['2017-6-13'],
value2: ''
}
}
}
</script>
<style>
.demo {
float:left;
margin:250px;
}
.label{
margin-right: 1em;
}
</style>
+7
View File
@@ -0,0 +1,7 @@
import Vue from 'vue'
import App from './App.vue'
new Vue({ // eslint-disable-line
el: '#app',
render: h => h(App)
})
+6
View File
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue2-datepicker</title>
</head>
<body>
<div id="app"></div>
<script src="dist/build.js"></script>
</body>
</html>
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "vue2-datepicker", "name": "vue2-datepicker",
"description": "A Datepicker Component For Vue2", "description": "A Datepicker Component For Vue2",
"main": "datepicker/index.vue", "main": "datepicker/index.vue",
"version": "1.2.1", "version": "1.5.0",
"scripts": { "scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot", "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules" "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
+71
View File
@@ -0,0 +1,71 @@
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './demo/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
// 'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true,
port: 9000
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: false,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}