├── _config.yml ├── .gitignore ├── .travis.yml ├── src ├── index.js └── vue-birthday-input.vue ├── .editorconfig ├── test ├── specs │ └── vue-birthday-input.spec.js └── karma.config.js ├── LICENSE ├── webpack.config.js ├── README.md ├── package.json ├── docs └── index.html └── dist └── vue-birthday-input.min.js /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | yarn-error.log 3 | node_modules 4 | .DS_Store 5 | /test/coverage/ 6 | /.vscode 7 | /.idea 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "7" 5 | 6 | before_script: 7 | - yarn install 8 | 9 | script: 10 | - yarn run lint 11 | - yarn run test 12 | - yarn run report-coverage -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import component from './vue-birthday-input.vue' 2 | 3 | const plugin = { 4 | install: Vue => { 5 | Vue.component(component.name, component) 6 | } 7 | } 8 | 9 | component.install = plugin.install 10 | 11 | export default component 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | tab_width = 2 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | 16 | [Makefile] 17 | indent_style = tab 18 | -------------------------------------------------------------------------------- /test/specs/vue-birthday-input.spec.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | import Vue from 'vue' 3 | import { expect } from 'chai' 4 | import { mount } from 'avoriaz' 5 | import birthdayInput from '@/vue-birthday-input' 6 | import sinon from 'sinon' 7 | 8 | describe('vue-birthday-input.vue', () => { 9 | it('默认测试', () => { 10 | const wrapper = mount(birthdayInput, { propsData: { value: '20120101' }}) 11 | expect(wrapper.data().birthday).to.equal('2012年01月01日') 12 | }) 13 | it('yyyy/mm/dd', () => { 14 | const wrapper = mount(birthdayInput, { propsData: { value: '20120101', formatView: 'yyyy/mm/dd' }}) 15 | expect(wrapper.data().birthday).to.equal('2012/01/01') 16 | }) 17 | it('yyyy-mm-dd', () => { 18 | const wrapper = mount(birthdayInput, { propsData: { value: '20120101', formatView: 'yyyy-mm-dd' }}) 19 | expect(wrapper.data().birthday).to.equal('2012-01-01') 20 | }) 21 | it('format-yyyy/mm/dd', () => { 22 | const wrapper = mount(birthdayInput, { propsData: { value: '2012/01/01', formatView: 'yyyy/mm/dd', format: 'yyyy/mm/dd' }}) 23 | expect(wrapper.data().birthday).to.equal('2012/01/01') 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Kong Fanbo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | const path = require('path') 3 | const CleanWebpackPlugin = require('clean-webpack-plugin') 4 | 5 | module.exports = { 6 | context: __dirname, 7 | resolve: { 8 | modules: [ 9 | path.resolve(__dirname, 'src'), 10 | 'node_modules' 11 | ], 12 | alias: { 13 | 'vue$': 'vue/dist/vue.esm.js' 14 | }, 15 | extensions: ['.js', '.json', '.vue'] 16 | }, 17 | entry: './src/index.js', 18 | externals: { 19 | 'moment': { 20 | commonjs: 'moment', 21 | commonjs2: 'moment', 22 | amd: 'moment', 23 | root: 'moment' 24 | } 25 | }, 26 | output: { 27 | path: path.resolve(__dirname, 'dist'), 28 | filename: "vue-birthday-input.min.js", 29 | library: 'VueBirthdayInput', 30 | libraryTarget: 'umd', 31 | umdNamedDefine: true 32 | }, 33 | module: { 34 | rules: [ 35 | { 36 | test: /\.vue$/, 37 | loader: 'vue-loader' 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | exclude: path.resolve(__dirname, 'node_modules') 43 | } 44 | ] 45 | }, 46 | plugins: [ 47 | new CleanWebpackPlugin(['./dist']) 48 | ], 49 | devtool: false, 50 | performance: { 51 | hints: false 52 | } 53 | } -------------------------------------------------------------------------------- /test/karma.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node, mocha */ 2 | 3 | var path = require('path') 4 | 5 | module.exports = config => { 6 | config.set({ 7 | browsers: ['PhantomJS'], 8 | frameworks: ['mocha', 'sinon-chai'], 9 | reporters: ['spec', 'coverage'], 10 | files: ['specs/*.spec.js'], 11 | preprocessors: { 12 | './specs/*.spec.js': ['webpack', 'sourcemap'] 13 | }, 14 | webpack: { 15 | devtool: '#inline-source-map', 16 | resolve: { 17 | extensions: ['.js', '.vue'], 18 | alias: { 19 | 'vue$': 'vue/dist/vue.esm.js', 20 | '@': path.resolve(__dirname, '../src') 21 | } 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.vue$/, 27 | loader: 'vue-loader', 28 | options: { 29 | esModule: false 30 | } 31 | }, 32 | { 33 | test: /\.js$/, 34 | loader: 'babel-loader', 35 | exclude: /node_modules/ 36 | } 37 | ] 38 | } 39 | }, 40 | webpackMiddleware: { 41 | noInfo: true 42 | }, 43 | coverageReporter: { 44 | dir: './coverage', 45 | reporters: [ 46 | { type: 'lcov', subdir: '.' }, 47 | { type: 'text-summary' } 48 | ] 49 | }, 50 | singleRun: true 51 | }) 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-birthday-input 2 | vue 生日输入组件 3 | 4 | npm install vue-birthday-input --save 5 | 6 | [![npm](https://img.shields.io/npm/v/vue-birthday-input.svg)](https://www.npmjs.com/package/vue-birthday-input) 7 | [![npm](https://img.shields.io/npm/dt/vue-birthday-input.svg)](https://www.npmjs.com/package/vue-birthday-input) 8 | [![npm](https://img.shields.io/npm/dm/vue-birthday-input.svg)](https://www.npmjs.com/package/vue-birthday-input) 9 | [![Build Status](https://travis-ci.org/xanke/vue-birthday-input.svg?branch=master)](https://travis-ci.org/xanke/vue-birthday-input) 10 | [![Codecov](https://img.shields.io/codecov/c/github/xanke/vue-birthday-input.svg)](https://codecov.io/gh/xanke/vue-birthday-input) 11 | [![npm](https://img.shields.io/npm/l/vue-birthday-input.svg)](http://opensource.org/licenses/MIT) 12 | 13 | 14 | #### 加入模块 15 | ```js 16 | import Vue from 'vue' 17 | import birthdayInput from 'vue-birthday-input' 18 | 19 | export default { 20 | name: 'App', 21 | 22 | components: { 23 | birthdayInput 24 | } 25 | } 26 | ``` 27 | 28 | ### 快速开始 29 | ```vue 30 | 33 | 34 | 49 | ``` 50 | 51 | ## Props 52 | |参数|说明|必须|类型|可选值|默认值| 53 | |-----|-----------|--------|----|----|-------| 54 | |placeholder|占位符|否|String|—|出生日期| 55 | |formatView|显示格式|否|String|yyyy/mm/dd / yyyy-mm-dd / mm/dd/yyyy|yyyy年mm月dd日| 56 | |format|输出格式|否|String|符合moment.format即可|YYYYMMDD| 57 | 58 | ## License 59 | 60 | Vue-birthday-input is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-birthday-input", 3 | "version": "0.8.6", 4 | "description": "Vue birthady input tool", 5 | "author": "xank", 6 | "main": "dist/vue-birthday-input.min.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/xanke/vue-birthday-input.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/xanke/vue-birthday-input/issues" 13 | }, 14 | "keywords": ["birthday", "input", "text", "vue", "vue.js"], 15 | "homepage": "https://github.com/xanke/vue-birthday-input", 16 | "license": "MIT", 17 | "dependencies": { 18 | "moment": "^2.19.2" 19 | }, 20 | "scripts": { 21 | "test": 22 | "cross-env BABEL_ENV=test ./node_modules/.bin/karma start test/karma.config.js", 23 | "test:watch": 24 | "cross-env BABEL_ENV=test ./node_modules/.bin/karma start test/karma.config.js --single-run=false", 25 | "lint": "./node_modules/.bin/eslint --ext .js,.vue src spec", 26 | "build": "./node_modules/.bin/webpack --hide-modules -p --progress", 27 | "report-coverage": "codecov" 28 | }, 29 | "devDependencies": { 30 | "avoriaz": "^4.0.0", 31 | "babel-core": "^6.26.0", 32 | "babel-loader": "^7.1.2", 33 | "babel-plugin-istanbul": "^4.1.4", 34 | "babel-preset-env": "^1.6.0", 35 | "chai": "^4.1.2", 36 | "clean-webpack-plugin": "^0.1.16", 37 | "codecov": "^2.3.0", 38 | "cross-env": "^5.0.5", 39 | "css-loader": "^0.28.7", 40 | "eslint": "^4.6.0", 41 | "eslint-plugin-vue": "3.13.1", 42 | "karma": "^1.7.1", 43 | "karma-coverage": "^1.1.1", 44 | "karma-mocha": "^1.3.0", 45 | "karma-phantomjs-launcher": "^1.0.4", 46 | "karma-sinon-chai": "^1.3.2", 47 | "karma-sourcemap-loader": "^0.3.7", 48 | "karma-spec-reporter": "^0.0.31", 49 | "karma-webpack": "^2.0.4", 50 | "mocha": "^3.5.0", 51 | "phantomjs-prebuilt": "^2.1.15", 52 | "sinon": "^3.2.1", 53 | "sinon-chai": "^2.13.0", 54 | "vue": "^2.4.2", 55 | "vue-loader": "^13.0.4", 56 | "vue-template-compiler": "^2.4.2", 57 | "webpack": "^3.5.5" 58 | }, 59 | "babel": { 60 | "presets": [ 61 | [ 62 | "env", 63 | { 64 | "uglify": true, 65 | "modules": false, 66 | "targets": { 67 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 68 | } 69 | } 70 | ] 71 | ], 72 | "env": { 73 | "test": { 74 | "plugins": ["istanbul"] 75 | } 76 | } 77 | }, 78 | "eslintConfig": { 79 | "extends": ["eslint:recommended", "plugin:vue/recommended"] 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vue-birthday-input demo 7 | 8 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |

20 | Vue Birthday Input 21 |

22 |

23 | Vuejs 生日输入控件 24 |

25 |
26 |
27 |
28 |
29 |
30 |
31 |

32 | 33 | 37 | 38 |

39 |
40 |
41 |
42 |
43 |
44 | 68 |
69 | 70 | 71 | 72 | 81 | 82 | -------------------------------------------------------------------------------- /dist/vue-birthday-input.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("moment")):"function"==typeof define&&define.amd?define("VueBirthdayInput",["moment"],e):"object"==typeof exports?exports.VueBirthdayInput=e(require("moment")):t.VueBirthdayInput=e(t.moment)}(this,function(t){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),i={install:function(t){t.component(r.a.name,r.a)}};r.a.install=i.install,e.default=r.a},function(t,e,n){"use strict";var r=n(3),i=n(5),o=n(2),a=o(r.a,i.a,!1,null,null,null);e.a=a.exports},function(t,e){t.exports=function(t,e,n,r,i,o){var a,s=t=t||{},u=typeof t.default;"object"!==u&&"function"!==u||(a=t,s=t.default);var d="function"==typeof s?s.options:s;e&&(d.render=e.render,d.staticRenderFns=e.staticRenderFns,d._compiled=!0),n&&(d.functional=!0),i&&(d._scopeId=i);var l;if(o?(l=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),r&&r.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(o)},d._ssrRegister=l):r&&(l=r),l){var c=d.functional,f=c?d.render:d.beforeCreate;c?(d._injectStyles=l,d.render=function(t,e){return l.call(e),f(t,e)}):d.beforeCreate=f?[].concat(f,l):[l]}return{esModule:a,exports:s,options:d}}},function(t,e,n){"use strict";var r=n(4),i=n.n(r);e.a={name:"vue-birthday-input",props:{placeholder:{default:"出生日期",type:String},format:{default:"YYYYMMDD",type:String},formatView:{default:"yyyy年mm月dd日",type:String},value:{default:"",required:!0,type:[Number,String]}},data:function(){return{birthday:"",bir:"",pos:0,elementId:"",isDelete:!1}},computed:{},methods:{onFocusHandler:function(t){this.$emit("focus",t)},onMouseoverHandel:function(){this.birthday||(this.birthday=this.formatView)},onMouseoutHandel:function(){this.birthday==this.formatView&&(this.birthday="")},getCursortPosition:function(){var t=document.getElementById(this.elementId),e=0;if(document.selection){var n=document.selection.createRange();n.moveStart("character",-t.value.length),e=n.text.length}else(t.selectionStart||"0"==t.selectionStart)&&(e=t.selectionStart);return e},setCaretPosition:function(t){var e=document.getElementById(this.elementId);if(e.setSelectionRange)setTimeout(function(){e.setSelectionRange(t,t)},0);else if(e.createTextRange){var n=e.createTextRange();n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",t),n.select()}},onDeleteHander:function(){var t=this.bir;t=t.split("");for(var e=0,n=0;n 2 | 14 | 15 | 213 | --------------------------------------------------------------------------------