Skip to content

重写 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"],
"comments": false,
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": [ "istanbul" ]
}
}
}
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
14 changes: 10 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
.DS_Store
node_modules/
npm-debug.log
.history
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.history
.vscode
.idea
.project
8 changes: 8 additions & 0 deletions .postcssrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config

module.exports = {
"plugins": {
// to edit target browsers: use "browserlist" field in package.json
"autoprefixer": {}
}
}
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

> 使用官方提供的vue-simple-template配置打包,写的一个简单的vue-datepicker。支持选择功能,功能比较简单,欢迎大家拍砖.
## 效果预览([demo](https://2ue.github.io/vue-datepicker))
## 效果预览([demo](https://2ue.github.io/vue-datepicker/dist/#/Datepicker))

![vue-datepicker](https://github.com/2ue/vue-datepicker/blob/master/src/gifShow/vue-datepicker2.gif)

@@ -23,6 +23,12 @@ npm run dev

## 更新记录

2017-5-10 22:01:41

- 合并到主分支
- 在devlop分支上重写
- 以前旧版本为v0.0

2017-3-23 16:21:27

- 修正选择日期后高亮错误问题
35 changes: 35 additions & 0 deletions build/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require('./check-versions')()

process.env.NODE_ENV = 'production'

var ora = require('ora')
var rm = require('rimraf')
var path = require('path')
var chalk = require('chalk')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')

var spinner = ora('building for production...')
spinner.start()

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')

console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
48 changes: 48 additions & 0 deletions build/check-versions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
var chalk = require('chalk')
var semver = require('semver')
var packageConfig = require('../package.json')
var shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}

var versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
},
]

if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}

module.exports = function () {
var warnings = []
for (var i = 0; i < versionRequirements.length; i++) {
var mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}

if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
9 changes: 9 additions & 0 deletions build/dev-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')

hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
89 changes: 89 additions & 0 deletions build/dev-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require('./check-versions')()

var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}

var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')

// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable

var app = express()
var compiler = webpack(webpackConfig)

var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})

var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})

// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
})

// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())

// serve webpack bundle output
app.use(devMiddleware)

// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)

// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))

var uri = 'http://localhost:' + port

var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
})

console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
})

var server = app.listen(port)

module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}
71 changes: 71 additions & 0 deletions build/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')

exports.assetsPath = function (_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}

exports.cssLoaders = function (options) {
options = options || {}

var cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap
}
}

// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
var loaders = [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}

// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}

// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}

// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
12 changes: 12 additions & 0 deletions build/vue-loader.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'

module.exports = {
loaders: utils.cssLoaders({
sourceMap: isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap,
extract: isProduction
})
}
58 changes: 58 additions & 0 deletions build/webpack.base.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {
return path.join(__dirname, '..', dir)
}

module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
35 changes: 35 additions & 0 deletions build/webpack.dev.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})

module.exports = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// cheap-module-eval-source-map is faster for development
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new FriendlyErrorsPlugin()
]
})
120 changes: 120 additions & 0 deletions build/webpack.prod.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})

if (config.build.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')

webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}

if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
6 changes: 6 additions & 0 deletions config/dev.env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
38 changes: 38 additions & 0 deletions config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')

module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}
3 changes: 3 additions & 0 deletions config/prod.env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
NODE_ENV: '"production"'
}
9,114 changes: 0 additions & 9,114 deletions dist/build.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/build.js.map

This file was deleted.

24 changes: 11 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-datepicker</title>
</head>
<body>
<div class="pageBox">
<div id="app"></div>
</div>
<script src="./dist/build.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue-date</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
89 changes: 62 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,62 @@
{
"name": "vue-simple-template",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "2ue <jie746635835@163.com>",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --inline --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"vue": "^2.1.0"
},
"devDependencies": {
"babel-core": "^6.0.0",
"babel-loader": "^6.0.0",
"babel-preset-es2015": "^6.0.0",
"cross-env": "^3.0.0",
"css-loader": "^0.25.0",
"file-loader": "^0.9.0",
"json-loader": "^0.5.4",
"vue-loader": "^10.0.0",
"vue-template-compiler": "^2.1.0",
"webpack": "^2.1.0-beta.25",
"webpack-dev-server": "^2.1.0-beta.0"
}
}
{
"name": "vue-date",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "2ue <jie746635835@163.com>",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js"
},
"dependencies": {
"vue": "^2.2.6",
"vue-router": "^2.3.1"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^1.1.3",
"connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.11.1",
"friendly-errors-webpack-plugin": "^1.1.3",
"html-webpack-plugin": "^2.28.0",
"http-proxy-middleware": "^0.17.3",
"less": "^2.7.2",
"less-loader": "^4.0.3",
"opn": "^4.0.2",
"optimize-css-assets-webpack-plugin": "^1.3.0",
"ora": "^1.2.0",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"url-loader": "^0.5.8",
"vue-loader": "^11.3.4",
"vue-style-loader": "^2.0.5",
"vue-template-compiler": "^2.2.6",
"webpack": "^2.3.3",
"webpack-bundle-analyzer": "^2.2.1",
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
309 changes: 24 additions & 285 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,293 +1,32 @@
<template>
<div id="app" class="content">
<div class="datePikcerInputBoX">
<input type="text" :value="chooseReslt" class="chooseTimeInput" @mouseout="hideDatePicker()" @click="showDatePicker" :year="chooseDate.year" :month="chooseDate.month" :day="chooseDate.day" readonly>
<span @click="clearChoosedTime" class="f_disselected">清空</span>
</div>
<div class="datePicker f_disselected" @mouseover="clearTimeWarpQue" @mouseout="hideDatePicker" v-if="showDatePickerBox">
<div class="datePickerHead" @mouseout="hideChooseBox()" @mouseover="clearTimeQue()">
<span @click="preMonth()" class="changeMomth">&lt;</span>
<span @click="showChooseYearBox()" class="chooseYearMonth">{{ chooseDate.year }}</span>
<span @click="showChooseMonthBox()" class="chooseYearMonth">{{ chooseDate.month }}</span>
<span @click="nxtMonth()" class="changeMomth">&gt;</span>
<!-- <Choosebox></Choosebox> -->
<div class="chooseBox"
:class="{'chooseYearBox':chooseType}"
v-show="showChooseBox">
<p class="yearPage" v-if="chooseType">
<span @click="changeYearPagePre()">&lt;</span>
<span @click="changeYearPageNxt()">&gt;</span>
</p>
<span class="item"
v-for="(item,index) in items"
@mouseover="clearTimeQue()"
@mouseout.stop="hideChooseBox(500)"
@click="chooseYearMonth(chooseType,item)"
>{{item}}</span>
</div>
</div>
<div class="datePickerBody">
<p><span v-for="(weekday,index) in weekdayArry" class="weekday">{{ weekday }}</span></p>
<p class="datePickerNum">
<span
class="day"
:class="{ 'u_cf30': item.color, 'hasHover': item.isCurMonth, 'isToday': item.isChoosed && item.isCurMonth}"
:title="item.isChoosed"
v-for="(item,index) in days"
@click="chooseDay(index)
">{{ item.dayNum }}</span>
</p>
</div>
</div>
<div id="app">
<img src="./assets/img/logo.png">
<h1 class="content-box">
<router-link to="/Datepicker">DatePicker</router-link>
</h1>
<router-view></router-view>
</div>
</template>

<script>
const curDate = new Date();
const curYear = curDate.getFullYear();
const curMonth = curDate.getMonth() + 1;
const curDay = curDate.getDate();
export default {
name: 'app',
data () {
return {
chooseReslt: '请选择时间',
chooseDate: {
year: '',
month: '',
day: ''
},
items: [1,2,3,4,5,6,7,8,9,10,11,12], //选择年月存放数据
days: getDayArry({year: curYear,month: curMonth,day:curDay}),
showChooseBox: false, //选择年月容器状态
showDatePickerBox: false, //日历容器
chooseBoxTimer: '', //定时器
datePickerBoxTimer: '', //定时器
chooseType: false, //选择年月界定,false为月(month),true为年(year)
weekdayArry: ['','','','','','',''],
YearChangeSyboml: '' //切换年月时标记
}
},
// computed: {
// items: function () {
// var startNum, endNum, tempArry = [];
// if(this.chooseType){
// startNum = this.chooseDate.year - 4;
// endNum = this.chooseDate.year + 4;
// }else{
// startNum = 1;
// endNum = 12;
// }
// for(var i = startNum; i <= endNum; i++){
// tempArry.push(i);
// };
// this.items = [];
// console.trace(tempArry);
// return tempArry;
// },
// chooseReslt: function () {
// return this.chooseDate.year || this.chooseDate.month || this.chooseDate.day ? (this.chooseDate.year + '-' + this.chooseDate.month + '-' + this.chooseDate.day) : '请选择时间';
// }
// },
watch: {
chooseDate: {
handler: function(val,oldVal){
this.days = getDayArry(this.chooseDate,this.chooseReslt);
},
deep: true
}
},
methods: {
//----------- 选择年月面板 START ---------------
showChooseYearBox: function() {//显示选择年
this.YearChangeSyboml = this.chooseDate.year;
this.showChooseBox = true;
this.chooseType = true;
this.getItems();
},
showChooseMonthBox: function() {//显示选择月
this.showChooseBox = true;
this.chooseType = false;
this.getItems();
},
hideChooseBox: function(time) {//隐藏选择年月
const self = this;
const t = time || 50;
self.chooseBoxTimer = setTimeout(function () {
self.showChooseBox = false;
}, t);
},
clearTimeQue: function() {//清除队列
clearTimeout(this.chooseBoxTimer);
},
chooseYearMonth: function(type,value) {//选择年月
const chooseType = !!type ? 'year' : 'month';
this.chooseDate[chooseType] = value || this.chooseDate[chooseType];
this.hideChooseBox();
},
getItems: function(){
let startNum, endNum, tempArry = [];
if(this.chooseType){
startNum = this.YearChangeSyboml - 4;
endNum = +this.YearChangeSyboml + 4;
}else{
startNum = 1;
endNum = 12;
}
for(let i = startNum; i <= endNum; i++){
tempArry.push(i);
};
this.items = tempArry;
},
//----------- 选择年月面板 END ---------------
//
//----------- 时间选择面板 START ---------------
showDatePicker: function(event) {//显示选择日期
const value = event.target.value;
const choosedDayArry = value.indexOf('-') > 0 ? value.split('-') : [curYear, curMonth, curDay];
this.showDatePickerBox = true;
this.chooseDate = {
year: choosedDayArry[0],
month: choosedDayArry[1],
day: choosedDayArry[2],
};
},
hideDatePicker: function(time) {
const self = this;
const t = time || 50;
self.datePickerBoxTimer = setTimeout(function () {
self.showDatePickerBox = false;
}, t)
},
clearTimeWarpQue: function() {
clearTimeout(this.datePickerBoxTimer);
},
//----------- 时间选择面板 END ---------------
//
//----------- 切换月 START ---------------
preMonth: function() {//上一月
const isFirstMonth = this.chooseDate.month == 1;
this.chooseDate.month = isFirstMonth ? 12 : this.chooseDate.month - 1;
this.chooseDate.year = isFirstMonth ? this.chooseDate.year - 1 : this.chooseDate.year;
},
nxtMonth: function() {//下一月
const isLastMonth = this.chooseDate.month == 12;
this.chooseDate.month = isLastMonth ? 1 : +this.chooseDate.month + 1;
this.chooseDate.year = isLastMonth ? +this.chooseDate.year + 1 : this.chooseDate.year;
},
//----------- 切换月 END ---------------
changeYearPagePre: function() {//年翻页:上一页
this.YearChangeSyboml = this.YearChangeSyboml - 12;
this.getItems();
},
changeYearPageNxt: function() {//年翻页:下一页
this.YearChangeSyboml = +this.YearChangeSyboml + 12;
this.getItems();
},
chooseDay: function(index) {//选择天
if(!!!index && index != 0) return;
if(!this.days[index].isCurMonth) return;
this.days[index].color = !this.days[index].color;
this.chooseDate.day = this.days[index].dayNum;
this.showDatePickerBox = false;
if(!this.chooseDate.year || !this.chooseDate.month || !this.chooseDate.day){
this.chooseReslt = '请选择时间';
}else{
this.chooseReslt = this.chooseDate.year + '-' + this.chooseDate.month + '-' + this.chooseDate.day;
}
},
//清空选择
clearChoosedTime: function(){
this.chooseDate.year = '';
this.chooseDate.month = '';
this.chooseDate.day = '';
this.chooseReslt = '请选择时间';
}
}
};
//-------------------------月份数组拼接 START------------------------------------
function getDayArry(showDate, chooseReslt) {
const year = showDate.year;
const month = showDate.month;
const day = showDate.day;
const chooseDateArry = !!chooseReslt && chooseReslt.indexOf('-') >= 0 ? chooseReslt.split('-') : [curYear,curMonth,curDay];
//获取当前月天数数组
const curMonthDays = getMonthDays(month);
const preMonthDays = getMonthDays(month == 0 ? 11 : month - 1);
// const nxtMonthDays = getMonthDays(month == 11 ? 0 : month + 1);
const firstDay = getDayInWeek(year, (month - 1), 1); //当前月第一天是星期几
const allDays = Math.ceil((+curMonthDays + firstDay) / 7) * 7;
let dayArry = [];
for(let i = 1; i <= allDays; i++){
const isPre = i <= firstDay;
const isNxt = i > (firstDay + curMonthDays);
const isCurMonth = !isPre && !isNxt;
const day = isPre ? preMonthDays - firstDay + i : isNxt ? i - firstDay - curMonthDays : i - firstDay;
dayArry.push({
dayNum: day,
isChoosed: (chooseDateArry[0] == year && chooseDateArry[1] == month && chooseDateArry[2] == (i - firstDay)),
isSpecailDay: false,
isCurMonth: isCurMonth,
color: false
})
};
return dayArry;
};
function getMonthDays(month) {
//获取某年某月有多少天
if(!!!month) return;
const tempDate = new Date(2016, month, 0).getDate();
return tempDate;
};
function getDayInWeek(year, month, day) {
//返回某年某月某日是星期几
if(!!!year || !!!month || !!!day || month - 1 < 0) return 0;
const tempDate = new Date(year, month, day).getDay();
return tempDate;
};
//-------------------------月份数组拼接 END------------------------------------
export default {
name: 'app'
}
</script>

<style>
@import url('./css/public.css');
.pageBox{padding: 100px 0;width:100%;min-width: 500px;color: #999;}
.content{margin: 0 auto;width:360px;}
.datePikcerInputBoX{position: relative;width: 100%;background: #fff;}
.chooseTimeInput{width:100%;box-sizing: border-box;height:35px;line-height:35px;border: 1px solid #9D94B0;font-size: 14px;text-indent: 1em;cursor: pointer;}
.datePikcerInputBoX span{float: right;position: absolute;top: 0;right: 0;display: inline-block;height: 35px;line-height: 35px;padding: 0 10px;border-left: 1px solid #9D94B0;cursor: pointer;}
.datePicker{margin-top:10px;}
.datePicker{width:350px;border: 1px solid #9D94B0;padding: 4px;background: #fff;}
.datePickerHead{/*height: 30px;*/color: #999;text-align: center;width: 100%;position: relative;margin-bottom: 10px;border-bottom: 1px solid #9D94B0;cursor: pointer;font-size: 0;}
.datePickerHead > span{display: inline-block;height: 50px;line-height: 50px;font-size: 16px;}
.datePickerHead > span:hover{color: #333;}
.datePickerHead .chooseYearMonth{width: 150px;}
.datePickerHead .changeMomth{font-family: aril;font-weight: bold;width: 25px;}
.datePickerHead .chooseBox {width:150px;overflow: hidden;border: 1px solid #9D94B0;background: #fff;position: absolute;top:50px;left:175px;z-index: 99;color: #666;}
.datePickerHead .chooseYearBox{left:25px;}
.datePickerHead .chooseBox > span{display: inline-block;height: 30px;line-height: 30px;width:50px;font-size:12px;cursor: pointer;text-align: center;border-top:1px solid #9D94B0;border-left:1px solid #9D94B0;margin: -1px 0 0 -1px;}
.datePickerHead .yearPage span{display: inline-block;height: 30px;line-height: 30px;width:50%;cursor: pointer;text-align: center;border-bottom:1px solid #9D94B0;font-size: 16px;font-family: aril;color: #333;}
.datePickerHead .chooseBox span:hover{background: #f8f8f8;color: #333;}
.datePickerBody{font-size: 0;}
.datePickerBody p{margin-left:-5px;}
.datePickerBody span{display: inline-block;width:45px;font-size: 12px;margin-bottom: 5px;text-align: center;border-radius: 5px;background: #fff;margin-left: 5px;height: 25px;line-height: 25px;color: #999;}
.datePickerBody .weekday{color: #666;}
.datePickerBody .weekday:nth-child(7n+1),
.datePickerBody .weekday:nth-child(7n),
.datePickerBody .hasHover:nth-child(7n+1),
.datePickerBody .hasHover:nth-child(7n){color: #f30;}
.datePickerBody .hasHover{background: #FAFAFA;color: #666;}
.datePickerBody .hasHover:hover{background: #B2B2B2;color: #fff;cursor: pointer;}
.datePickerBody .isToday,
.datePickerBody .hasHover.u_cf30{color: #fff;background: #8585AD;}
</style>
@import url('./assets/css/public.css');
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
img{
width: 80px;
height: auto;
}
.content-box{padding: 20px 0;}
</style>
File renamed without changes.
Binary file added src/assets/img/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
287 changes: 287 additions & 0 deletions src/components/DatePanel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
<template>
<div class="date_panel f_disselected"
v-if="panelStatus"
@mouseover="clearPanelTimer"
@mouseout="hidePanel"
@click="hidePickerNow">
<div class="panel_head" >
<span class="change_month" @click="changeMonth(-1)">&lt;</span>
<span class="choose_btn" @click="showPicker" @mouseout="hidePicker" choosetype="y">{{panelChoosed.year}}</span>
<span class="choose_btn" @click="showPicker" @mouseout="hidePicker" choosetype="m">{{panelChoosed.month}}</span>
<span class="change_month" @click="changeMonth(1)">&gt;</span>
<div class="choose_box"
:class="{'choose_year_box':changeType === 'y'}"
@mouseover="clearPickerTimer"
@mouseout="hidePicker"
v-show="showChooseBox">
<p class="change_year" v-if="changeType === 'y'">
<span @click="changeYearPage" changeval="-8">&lt;</span>
<span @click="changeYearPage" changeval="8">&gt;</span>
</p>
<span class="item"
v-for="(item,index) in items"
@click="chooseYearMonth(item)"
>{{item}}</span>
</div>
</div>
<div class="panel_body">
<p class="weekday_box"><span v-for="(weekday,index) in weekdayArry" class="weekday">{{ weekday }}</span></p>
<div class="day_box">
<span v-for="(item,index) in days"
:class="{'crn_month':item.isCurMonth,'only_day': item.isChoosed && item.isCurMonth}"
@click="choosDay(item.dayNum,item.isCurMonth)">{{ item.dayNum }}</span>
</div>
</div>
</div>
</template>
<script>
var curDate = new Date();
var curYear = curDate.getFullYear();
var curMonth = curDate.getMonth() + 1;
var curDay = curDate.getDate();
export default {
name: 'dataPanel',
props: ['panelStatus','clearPanelTimer','hidePanel','choosed'],
data () {
return {
weekdayArry: ['','','','','','',''],
showChooseBox: false,
changeYear: '',
//渲染切换年或者月的标记,''表示不渲染,'y'表示年,‘m’表示切换月
changeType: '',
panelChoosed:{
year: this.choosed.year ? this.choosed.year : curYear,
month: this.choosed.month ? this.choosed.month : curMonth
},
hidePickerTimer: ''
}
},
computed: {
days: function () {
return getDayArry(this.panelChoosed,this.choosed)
},
items: function () {
var type = this.changeType;
var reslt = [];
var start = 0, end = 0;
if(type === 'y' && this.changeYear) {
start = this.changeYear - 4;
end = this.changeYear + 4;
};
if(type === 'm') {
start = 1;
end = 12;
};
for(var i = start; i <= end; i++){
reslt.push(i);
};
return reslt;
}
},
methods: {
changeMonth: function (_val) {
var _self = this;
if(!_val || isNaN(_val)) return;
var month = _self.panelChoosed.month + _val;
switch (month) {
case (0):{
_self.panelChoosed.year = _self.panelChoosed.year - 1;
_self.panelChoosed.month = 12;
break;
};
case (13):{
_self.panelChoosed.year = _self.panelChoosed.year + 1;
_self.panelChoosed.month = 1;
break;
};
default:{
_self.panelChoosed.month = _self.panelChoosed.month + _val;
break;
}
}
},
showPicker: function(event){
event.stopPropagation();
var type = event.target.getAttribute('choosetype');
this.clearPickerTimer();
this.changeType = type ? type : 'm';
this.changeYear = this.panelChoosed.year;
this.showChooseBox = true;
},
hidePicker: function(){
var _self = this;
_self.clearPickerTimer();
_self.hidePickerTimer = setTimeout(function(){
_self.showChooseBox = false;
}, 500)
},
hidePickerNow: function(){
this.clearPickerTimer();
this.showChooseBox = false;
},
clearPickerTimer: function(){
clearTimeout(this.hidePickerTimer);
},
chooseYearMonth: function(_val){
this.changeType === 'y' ? this.panelChoosed.year = _val : this.panelChoosed.month = _val;
this.showChooseBox = false;
},
changeYearPage: function(event){
event.stopPropagation();
var _val = parseInt(event.target.getAttribute('changeval'));
this.changeYear = this.changeYear + _val;
},
choosDay: function (_day,_isCurMonth) {
if(!_isCurMonth) return;
this.choosed.year = this.panelChoosed.year;
this.choosed.month = this.panelChoosed.month;
this.choosed.day = _day;
this.hidePanel(4)
}
}
};
//-------------------------月份数组拼接 START------------------------------------
function getDayArry(showDate, chooseReslt) {
var year = showDate.year;
var month = showDate.month;
var day = showDate.day;
var chooseDateArry = chooseReslt.year && chooseReslt.month && chooseReslt.day ? [chooseReslt.year,chooseReslt.month,chooseReslt.day] : [curYear,curMonth,curDay];
//获取当前月天数数组
var curMonthDays = getMonthDays(month);
var preMonthDays = getMonthDays(month == 0 ? 11 : month - 1);
var firstDay = getDayInWeek(year, (month - 1), 1); //当前月第一天是星期几
var allDays = Math.ceil((+curMonthDays + firstDay) / 7) * 7;
let dayArry = [];
for(let i = 1; i <= allDays; i++){
var isPre = i <= firstDay;
var isNxt = i > (firstDay + curMonthDays);
var isCurMonth = !isPre && !isNxt;
var day = isPre ? preMonthDays - firstDay + i : isNxt ? i - firstDay - curMonthDays : i - firstDay;
dayArry.push({
dayNum: day,
isChoosed: (chooseDateArry[0] == year && chooseDateArry[1] == month && chooseDateArry[2] == (i - firstDay)),
isSpecailDay: false,
isCurMonth: isCurMonth,
color: false
})
};
return dayArry;
};
function getMonthDays(month) {
//获取某年某月有多少天
if(!!!month) return;
var tempDate = new Date(2016, month, 0).getDate();
return tempDate;
};
function getDayInWeek(year, month, day) {
//返回某年某月某日是星期几
if(!!!year || !!!month || !!!day || month - 1 < 0) return 0;
var tempDate = new Date(year, month, day).getDay();
return tempDate;
};
//-------------------------月份数组拼接 END------------------------------------
</script>
<style lang="less" scoped>
.date_panel {
margin-top: 10px;
}
.date_panel {
width: 350px;
border: 1px solid #9D94B0;
padding: 4px;
background: #fff;
}
.panel_head{
position: relative;
height: 40px;
line-height: 40px;
font-size: 0;
margin-bottom: 5px;
span{
display: inline-block;
font-size: 16px;
color: #666;
cursor: pointer;
&:hover{
background: #F0F0F0;
}
}
.change_month{
width:50px;
}
.choose_btn{
width: 120px;
}
}
.choose_box{
position: absolute;
top:45px;
left: 175px;
width: 120px;
background: #fff;
border: 1px solid #9D94B0;
font-size: 0;
line-height: 25px;
span{
display: inline-block;
width: 40px;
height: 25px;
font-size: 12px;
}
.change_year span{
width: 50%;
font-size: 16px;
}
&.choose_year_box{
left: 55px;
}
}
.panel_body{
border-top: 1px solid #9D94B0;
font-size: 0;
span{
display: inline-block;
width:50px;
height: 30px;
line-height: 30px;
font-size: 12px;
color: #666;
}
span:nth-child(7n),
span:nth-child(7n+1){
color: #f30;
}
.day_box span{
width:40px;
margin:5px;
border-radius: 3px;
cursor: pointer;
}
.day_box span:not(.crn_month){
color: #999;
cursor: inherit;
}
.day_box .only_day,.crn_month:hover{
background: #141414;
color: #fff;
}
}
</style>

101 changes: 101 additions & 0 deletions src/components/Datepicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<template>
<div class="date_picker">
<div class="date_input_box">
<input type="text" class="date_input" readonly :value="reslt" @click="showPanel" @mouseout="hidePanel">
<span class="f_disselected" @click="clearChoosed">清空</span>
</div>
<datePanel :panelStatus="panelStatus" :clearPanelTimer="clearPanelTimer" :hidePanel="hidePanel" :choosed="choosed"></datePanel>
</div>
</template>
<script>
import DatePanel from './DatePanel'
export default {
name: 'datepicker',
components:{ DatePanel },
data () {
return {
//panel是否显示
panelStatus: false,
//一个setTimeout的储存器
panelTimer:'',
//保存选择的年月日
choosed:{
year: '',
month: '',
day: ''
}
}
},
computed: {
//根据选择的年月计算最终显示的结果
reslt:function () {
var _self = this;
var year = _self.choosed.year;
var month = _self.choosed.month;
var day = _self.choosed.day;
return !year || !month || !day ? 'please choose date' : (year + '-' + month + '-' + day);
}
},
methods: {
showPanel: function () {
this.panelStatus = true;
},
hidePanel: function (_t) {
var _self = this;
_self.clearPanelTimer();
var timer = !!_t && !isNaN(parseInt(_t)) ? parseInt(_t) : 500;
_self.panelTimer = setTimeout(function() {
_self.panelStatus = false;
}, timer);
},
clearPanelTimer: function () {
clearTimeout(this.panelTimer);
},
clearChoosed: function(){
this.choosed = {
year: '',
month: '',
day: ''
}
}
}
}
</script>
<style lang="less" scoped>
.date_picker {
width: 360px;
margin: 20px auto;
}
.date_input_box {
position: relative;
width: 100%;
background: #fff;
span {
display: inline-block;
float: right;
position: absolute;
top: 0;
right: 0;
height: 35px;
line-height: 35px;
padding: 0 10px;
border-left: 1px solid #9D94B0;
cursor: pointer;
}
}
.date_input {
width: 100%;
box-sizing: border-box;
height: 35px;
line-height: 35px;
border: 1px solid #9D94B0;
font-size: 14px;
text-indent: 1em;
cursor: pointer;
}
</style>

37 changes: 37 additions & 0 deletions src/components/Hello.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>

<script>
export default {
name: 'hello',
data () {
return {
msg: 'Welcome use the datePicker!'
}
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
Binary file removed src/gifShow/vue-datepicker.gif
Binary file not shown.
Binary file removed src/gifShow/vue-datepicker2.gif
Binary file not shown.
22 changes: 15 additions & 7 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import Vue from 'vue'
import App from './App.vue'

new Vue({
el: '#app',
render: h => h(App)
})
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
21 changes: 21 additions & 0 deletions src/router/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import Datepicker from '@/components/Datepicker'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'Hello',
component: Hello
},
{
path: '/datepicker',
name: 'Datepicker',
component: Datepicker
}
]
})
Empty file added static/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions static/css/app.81a5f0a9d05043d10d1db48b9b391650.css
1 change: 1 addition & 0 deletions static/css/app.81a5f0a9d05043d10d1db48b9b391650.css.map
2 changes: 2 additions & 0 deletions static/js/app.55239ecdb4d8634f3c6c.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions static/js/app.55239ecdb4d8634f3c6c.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions static/js/manifest.a71c0c6fb7e4575ccdb7.js
1 change: 1 addition & 0 deletions static/js/manifest.a71c0c6fb7e4575ccdb7.js.map
7 changes: 7 additions & 0 deletions static/js/vendor.a45b2db43f551b851e94.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions static/js/vendor.a45b2db43f551b851e94.js.map

Large diffs are not rendered by default.

65 changes: 0 additions & 65 deletions webpack.config.js

This file was deleted.