mirror of
https://github.com/tenrok/vue2-datepicker.git
synced 2026-06-22 22:20:36 +03:00
Merge branch 'gh-pages'
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
["latest", {
|
||||||
|
"es2015": { "modules": false }
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# vue2-datepicker
|
||||||
|
|
||||||
|
> A Vue.js project
|
||||||
|
|
||||||
|
## Build Setup
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
# install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# serve with hot reload at localhost:8080
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# build for production with minification
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader).
|
||||||
+11
@@ -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>
|
||||||
+20
-9
@@ -1,15 +1,26 @@
|
|||||||
{
|
{
|
||||||
"name": "vue2-datepicker",
|
"name": "vue2-datepicker",
|
||||||
|
"description": "A Vue.js project",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "datepicker for Vue2",
|
"author": "Mengxiong10 <15623530292@163.com>",
|
||||||
"main": "index.vue",
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
|
||||||
|
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"dependencies": {
|
||||||
"vue",
|
"vue": "^2.2.1"
|
||||||
"datepicker"
|
},
|
||||||
],
|
"devDependencies": {
|
||||||
"author": "xmx",
|
"babel-core": "^6.0.0",
|
||||||
"license": "MIT"
|
"babel-loader": "^6.0.0",
|
||||||
|
"babel-preset-latest": "^6.0.0",
|
||||||
|
"cross-env": "^3.0.0",
|
||||||
|
"css-loader": "^0.25.0",
|
||||||
|
"file-loader": "^0.9.0",
|
||||||
|
"vue-loader": "^11.1.4",
|
||||||
|
"vue-template-compiler": "^2.2.1",
|
||||||
|
"webpack": "^2.2.0",
|
||||||
|
"webpack-dev-server": "^2.2.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<div class="demo">
|
||||||
|
<span class="label">默认:</span>
|
||||||
|
<date-picker v-model="value1"></date-picker>
|
||||||
|
</div>
|
||||||
|
<div class="demo">
|
||||||
|
<span class="label">range:</span>
|
||||||
|
<date-picker v-model="value2" range></date-picker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DatePicker from './datepicker/index.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'app',
|
||||||
|
components:{ DatePicker },
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
value1:'2015-10-10',
|
||||||
|
value2:'',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.demo {
|
||||||
|
float:left;
|
||||||
|
margin:60px;
|
||||||
|
}
|
||||||
|
.label{
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -29,8 +29,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { formatDate } from './utils.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
startAt: null,
|
startAt: null,
|
||||||
@@ -42,69 +40,65 @@ export default {
|
|||||||
return {
|
return {
|
||||||
days: ['日', '一', '二', '三', '四', '五', '六'],
|
days: ['日', '一', '二', '三', '四', '五', '六'],
|
||||||
dates: [],
|
dates: [],
|
||||||
now: this.value ? new Date(this.value) : new Date(),
|
now: new Date(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.update()
|
this.updateCalendar()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
show(val) {
|
show(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.now = this.value ? new Date(this.value) : new Date()
|
this.updateNow()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
value(val) {
|
value: {
|
||||||
this.now = val ? new Date(val) : new Date()
|
handler:'updateNow',
|
||||||
|
immediate: true,
|
||||||
},
|
},
|
||||||
now: 'update',
|
now: 'updateCalendar',
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getCalendar(time, firstday, length, classes) {
|
updateNow() {
|
||||||
const today = new Date().setHours(0, 0, 0, 0)
|
let now = this.value ? new Date(this.value) : new Date()
|
||||||
return Array.apply(null, { length }).map((v, i) => { // eslint-disable-line
|
now.setDate(1)
|
||||||
let day = firstday + i
|
this.now = now
|
||||||
let type = classes
|
|
||||||
const date = new Date(time.getFullYear(), time.getMonth(), day)
|
|
||||||
const isToday = today === date.getTime()
|
|
||||||
if (isToday) {
|
|
||||||
day = '今天'
|
|
||||||
type += ' today'
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
title: formatDate(date, 'yyyy-MM-dd'),
|
|
||||||
date,
|
|
||||||
day,
|
|
||||||
type,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
// 更新面板选择时间
|
// 更新面板选择时间
|
||||||
update() {
|
updateCalendar() {
|
||||||
const row = 6
|
function getCalendar(time, firstday, length, classes) {
|
||||||
const col = 7
|
return Array.apply(null, { length }).map((v, i) => { // eslint-disable-line
|
||||||
|
let day = firstday + i
|
||||||
|
const date = new Date(time.getFullYear(), time.getMonth(), day)
|
||||||
|
return {
|
||||||
|
title: date.toLocaleDateString(),
|
||||||
|
date,
|
||||||
|
day,
|
||||||
|
classes,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
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() + 1 // time.getDay() 0是星期天, 1是星期一 ...
|
||||||
const lastMonthfirst = time.getDate() - (lastMonthLength - 1)
|
const lastMonthfirst = time.getDate() - (lastMonthLength - 1)
|
||||||
const lastMonth = this.getCalendar(time, lastMonthfirst, lastMonthLength, 'lastMonth')
|
const lastMonth = getCalendar(time, lastMonthfirst, lastMonthLength, 'lastMonth')
|
||||||
|
|
||||||
time.setMonth(time.getMonth() + 2, 0) // 切换到这个月最后一天
|
time.setMonth(time.getMonth() + 2, 0) // 切换到这个月最后一天
|
||||||
const curMonthLength = time.getDate()
|
const curMonthLength = time.getDate()
|
||||||
const curMonth = this.getCalendar(time, 1, curMonthLength, 'curMonth')
|
const curMonth = getCalendar(time, 1, curMonthLength, 'curMonth')
|
||||||
|
|
||||||
time.setMonth(time.getMonth() + 1, 1)
|
time.setMonth(time.getMonth() + 1, 1)
|
||||||
const nextMonthLength = (row * col) - (lastMonthLength + curMonthLength)
|
const nextMonthLength = 42 - (lastMonthLength + curMonthLength)
|
||||||
const nextMonth = this.getCalendar(time, 1, nextMonthLength, 'nextMonth')
|
const nextMonth = getCalendar(time, 1, nextMonthLength, 'nextMonth')
|
||||||
|
|
||||||
// 分割数组
|
// 分割数组
|
||||||
let index = 0
|
let index = 0
|
||||||
let resIndex = 0
|
let resIndex = 0
|
||||||
const arr = lastMonth.concat(curMonth, nextMonth)
|
const arr = lastMonth.concat(curMonth, nextMonth)
|
||||||
const result = new Array(row)
|
const result = new Array(6)
|
||||||
while (index < row * col) {
|
while (index < 42) {
|
||||||
result[resIndex++] = arr.slice(index, index += col)
|
result[resIndex++] = arr.slice(index, index += 7)
|
||||||
}
|
}
|
||||||
this.dates = result
|
this.dates = result
|
||||||
},
|
},
|
||||||
@@ -112,10 +106,19 @@ export default {
|
|||||||
const classes = []
|
const classes = []
|
||||||
const cellTime = cell.date.getTime()
|
const cellTime = cell.date.getTime()
|
||||||
const curTime = this.value ? new Date(this.value).setHours(0, 0, 0, 0) : 0
|
const curTime = this.value ? new Date(this.value).setHours(0, 0, 0, 0) : 0
|
||||||
const startTime = this.startAt ? this.startAt.setHours(0, 0, 0, 0) : 0
|
const startTime = this.startAt ? new Date(this.startAt).setHours(0, 0, 0, 0) : 0
|
||||||
const endTime = this.endAt ? this.endAt.setHours(0, 0, 0, 0) : 0
|
const endTime = this.endAt ? new Date(this.endAt).setHours(0, 0, 0, 0) : 0
|
||||||
classes.push(cell.type)
|
const today = new Date().setHours(0, 0, 0, 0)
|
||||||
if (startTime) {
|
|
||||||
|
classes.push(cell.classes)
|
||||||
|
|
||||||
|
if (cellTime === today) {
|
||||||
|
classes.push('today')
|
||||||
|
}
|
||||||
|
// range classes
|
||||||
|
if (cellTime === curTime) {
|
||||||
|
classes.push('current')
|
||||||
|
} else if (startTime) {
|
||||||
if (cellTime < startTime) {
|
if (cellTime < startTime) {
|
||||||
classes.push('disabled')
|
classes.push('disabled')
|
||||||
} else if (curTime && cellTime <= curTime) {
|
} else if (curTime && cellTime <= curTime) {
|
||||||
@@ -128,20 +131,16 @@ export default {
|
|||||||
classes.push('inrange')
|
classes.push('inrange')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curTime === cellTime) {
|
|
||||||
classes.push('current')
|
|
||||||
}
|
|
||||||
return classes.join(' ')
|
return classes.join(' ')
|
||||||
},
|
},
|
||||||
changeYear(flag) {
|
changeYear(flag) {
|
||||||
const now = new Date(this.now)
|
const now = new Date(this.now)
|
||||||
now.setDate(1)
|
|
||||||
now.setFullYear(now.getFullYear() + flag)
|
now.setFullYear(now.getFullYear() + flag)
|
||||||
this.now = now
|
this.now = now
|
||||||
},
|
},
|
||||||
changeMonth(flag) {
|
changeMonth(flag) {
|
||||||
const now = new Date(this.now)
|
const now = new Date(this.now)
|
||||||
now.setDate(1)
|
|
||||||
now.setMonth(now.getMonth() + flag)
|
now.setMonth(now.getMonth() + flag)
|
||||||
this.now = now
|
this.now = now
|
||||||
},
|
},
|
||||||
@@ -150,7 +149,6 @@ export default {
|
|||||||
if (classes.indexOf('disabled') !== -1) {
|
if (classes.indexOf('disabled') !== -1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.now = cell.date
|
|
||||||
this.$emit('input', cell.date)
|
this.$emit('input', cell.date)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -165,8 +163,8 @@ export default {
|
|||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar:nth-child(2) {
|
.calendar * {
|
||||||
border-left: 1px solid #e4e4e4;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-header {
|
.calendar-header {
|
||||||
@@ -24,15 +24,14 @@
|
|||||||
<div class="datepicker-top">
|
<div class="datepicker-top">
|
||||||
<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%" 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)" 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>
|
<calendar-panel style="width:50%;" v-model="currentValue[1]" :start-at="currentValue[0]" :show="showPopup"></calendar-panel>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { formatDate } from './utils.js'
|
|
||||||
import CalendarPanel from './calendar-panel.vue'
|
import CalendarPanel from './calendar-panel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -123,8 +122,29 @@ export default {
|
|||||||
this.togglePopup()
|
this.togglePopup()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
formatDate(date, fmt) {
|
||||||
|
const map = {
|
||||||
|
'M+': date.getMonth() + 1, // 月份
|
||||||
|
'[Dd]+': date.getDate(), // 日
|
||||||
|
'[Hh]+': date.getHours(), // 小时
|
||||||
|
'm+': date.getMinutes(), // 分
|
||||||
|
's+': date.getSeconds(), // 秒
|
||||||
|
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
|
||||||
|
'S': date.getMilliseconds(), // 毫秒
|
||||||
|
}
|
||||||
|
let str = fmt.replace(/[Yy]+/g, function (str) {
|
||||||
|
return ('' + date.getFullYear()).slice(4 - str.length)
|
||||||
|
})
|
||||||
|
Object.keys(map).forEach((key) => {
|
||||||
|
str = str.replace(new RegExp(key), function (str) {
|
||||||
|
const value = '' + map[key]
|
||||||
|
return str.length === 1 ? value : ('00' + value).slice(value.length)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
},
|
||||||
stringify(date) {
|
stringify(date) {
|
||||||
return formatDate(date, this.format)
|
return this.formatDate(new Date(date), this.format)
|
||||||
},
|
},
|
||||||
isValidDate(date) {
|
isValidDate(date) {
|
||||||
return !!new Date(date).getTime()
|
return !!new Date(date).getTime()
|
||||||
@@ -193,7 +213,6 @@ export default {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
color:#73879c;
|
color:#73879c;
|
||||||
font: 14px/1.5 "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei", sans-serif;
|
font: 14px/1.5 "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei", sans-serif;
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.datepicker * {
|
.datepicker * {
|
||||||
@@ -202,7 +221,7 @@ export default {
|
|||||||
|
|
||||||
.datepicker-popup {
|
.datepicker-popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
min-width: 234px;
|
width: 234px;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
border: 1px solid #d9d9d9;
|
border: 1px solid #d9d9d9;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
@@ -211,7 +230,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.range {
|
.range {
|
||||||
min-width: 468px;
|
width: 468px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
render: h => h(App)
|
||||||
|
})
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
export function formatDate(date, fmt = 'YYYY-MM-DD hh:mm:ss') {
|
|
||||||
date = date instanceof Date ? date : new Date(date)
|
|
||||||
const map = {
|
|
||||||
'M+': date.getMonth() + 1, // 月份
|
|
||||||
'[Dd]+': date.getDate(), // 日
|
|
||||||
'[Hh]+': date.getHours(), // 小时
|
|
||||||
'm+': date.getMinutes(), // 分
|
|
||||||
's+': date.getSeconds(), // 秒
|
|
||||||
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
|
|
||||||
'S': date.getMilliseconds(), // 毫秒
|
|
||||||
}
|
|
||||||
fmt = fmt.replace(/[Yy]+/g, function (str) {
|
|
||||||
return ('' + date.getFullYear()).slice(4 - str.length)
|
|
||||||
})
|
|
||||||
Object.keys(map).forEach((key) => {
|
|
||||||
fmt = fmt.replace(new RegExp(key), function (str) {
|
|
||||||
const value = '' + map[key]
|
|
||||||
return str.length === 1 ? value : ('00' + value).slice(value.length)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return fmt
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
var path = require('path')
|
||||||
|
var webpack = require('webpack')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/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: true,
|
||||||
|
compress: {
|
||||||
|
warnings: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user