2
0
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:
Mengxiong10
2017-05-08 22:48:20 +08:00
10 changed files with 244 additions and 87 deletions
+7
View File
@@ -0,0 +1,7 @@
{
"presets": [
["latest", {
"es2015": { "modules": false }
}]
]
}
+18
View File
@@ -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
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>
+20 -9
View File
@@ -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
View File
@@ -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 {
+26 -7
View File
@@ -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 {
+7
View File
@@ -0,0 +1,7 @@
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
-22
View File
@@ -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
}
+71
View File
@@ -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
})
])
}