├── .gitignore ├── LICENSE ├── README.md ├── dist ├── vue-ios-pickers.js └── vue-ios-pickers.min.js ├── index.html ├── package.json ├── qrCode.png ├── src ├── index.es5.js ├── index.js ├── picker.es5.vue └── picker.vue ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 音十 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## vue-ios-pickers 组件使用说明 2 | 基于Vue,iOS风格的picker组件,支持三级联动,日期(年.月.日),时间(时:分),日期+时间,年,年+月 3 | ### DEMO 4 | [查看demo](https://yuanwing.github.io/vue-ios-pickers/) 5 | ![vue-ios-pickers](./qrCode.png) 6 | ### 安装 7 | ``` 8 | $ yarn add vue-ios-pickers 9 | ``` 10 | Or 11 | ``` 12 | $ npm install vue-ios-pickers 13 | ``` 14 | ### 使用 15 | - 引入`js`全局使用: 16 | ```javascript 17 | 18 | ``` 19 | - 使用 `Vue.use` 导入 20 | ```javascript 21 | import VueIosPickers from 'vue-ios-pickers'; 22 | Vue.use(VueIosPickers); 23 | ``` 24 | - 页面中使用 25 | ```javascript 26 | // 一个日期的 picker 支持 年.月.日 时:分 27 | 31 | ``` 32 | ### 属性说明: 33 | | 属性 | 描述 | 类型 | 默认值 | 34 | | --- | --- | --- | --- | 35 | | v-model | 组件通信, 初始值(**必填**) | String | Number | Array | `-` | 36 | | cols | 展示数据的列数, 可取值 `1`, `2`, `3`, `5` | Number | `3` | 37 | | name | 设置 `picker` 的唯一名称, 会在 `onConfirm` 一起返回 | String | `-` | 38 | | placeholder | 设置 `picker` 的默认文字 | String | `请选择` | 39 | | align | 设置文本对齐方式, 可取值 `css -> text-align` | String | `right` 40 | | pickerData | 需要展示的数据 | Array | `[]` | 41 | | date | 设置日期类型, 可取值 `date`, `time`, `datetime`, (`pickerData` 将失效) | String | `-` | 42 | | minDate | 开始时间 | Number | `1949` | 43 | | maxDate | 结束时间 | Number | `当前年份往后 + 50` | 44 | | onCancel | 取消的回调函数 | Function | `-` | 45 | | onConfirm | 确认的回调函数 | Function | `当前选中的数据(Array)及name值` | 46 | | onItemChange | 列数据变更的回调函数 | Function | `变更前、后的数据` | 47 | ### 其他说明 48 | 1. 当使用 `date=datetime` 时, `cols=5`; 49 | 2. 使用 `v-model` 进行数据传输, 如果需要初始默认值, 刚把默认值赋值给 `v-model`; 50 | 3. `date=datetime` 取值格式必须是 `年.月.日 时:分` 51 | 4. 默认值格式: 如果存在 `date`, 则必须是 `String`, 否则可以是`String` 或 `Array`: 52 | - `date`存在的`String`: `2018.08.19 08:08` 53 | - `Array`: `['北京', '西城区', '西长椿街']` 54 | - `String`: `北京,西城区,西长椿街` 55 | 5. 三级联动时, 后一列的数据取前一列的 `children` 属性值 56 | 6. 新增 `date` 属性存在时, 年份支持 **长期有效(id='-1')** 57 | 7. `pickerData`的数据格式: 58 | ``` 59 | [ 60 | [ 61 | { 62 | name: '北京', 63 | id: '010', 64 | children: [ 65 | { 66 | name: '北京', 67 | id: '0101', 68 | children: [ 69 | { name: '西城区', id: '010101' }, 70 | { name: '东城区', id: '010102' }, 71 | { name: '海淀区', id: '010103' }, 72 | ] 73 | } 74 | ] 75 | }, { 76 | name: '四川', 77 | id: '028', 78 | children: [ 79 | { 80 | name: '成都市', 81 | id: '0281', 82 | children: [ 83 | { name: '武侯区', id: '02811' }, 84 | { name: '青羊区', id: '02812' }, 85 | { name: '成华区', id: '02813' }, 86 | { name: '锦江区', id: '02814' }, 87 | { name: '金牛区', id: '02815' }, 88 | ] 89 | }, { 90 | name: '泸州市', 91 | id: '0282', 92 | children: [ 93 | { name: '江阳区', id: '02821' }, 94 | { name: '龙马潭区', id: '02822' }, 95 | { name: '纳西区', id: '02823' }, 96 | { name: '泸县', id: '02824' }, 97 | ] 98 | } 99 | ] 100 | } 101 | ] 102 | ] 103 | ``` -------------------------------------------------------------------------------- /dist/vue-ios-pickers.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./src/picker.vue?vue&type=script&lang=js": 90 | /*!******************************************************************************************************************************************!*\ 91 | !*** ./node_modules/babel-loader/lib??ref--1!./node_modules/vue-loader/lib??vue-loader-options!./src/picker.vue?vue&type=script&lang=js ***! 92 | \******************************************************************************************************************************************/ 93 | /*! no static exports found */ 94 | /***/ (function(module, exports, __webpack_require__) { 95 | 96 | "use strict"; 97 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\nvar IS_LONG = '长期有效';\nexports.default = {\n name: 'vue-ios-pickers',\n props: {\n cols: {\n type: Number,\n default: 3\n },\n pickerData: {\n type: Array,\n default: function _default() {\n return [];\n }\n },\n date: String,\n minDate: [Number, String],\n maxDate: [Number, String],\n value: {\n default: '',\n type: [Array, String, Number]\n },\n onCancel: Function,\n onConfirm: Function,\n onItemChange: Function,\n name: String,\n placeholder: {\n type: String,\n default: '请选择'\n },\n align: {\n type: String,\n default: 'right'\n },\n isLong: {\n type: Boolean,\n default: false\n }\n },\n data: function data() {\n return {\n pickerValue: '',\n show: false,\n itemHeight: 0,\n // 实际页面展示的数据\n colsData: [],\n pos: []\n };\n },\n\n watch: {\n show: function show(val) {\n if (val) this.init();\n },\n value: function value(val) {\n if (val || val === 0) this.init();\n }\n },\n // created() {\n // this.pickerValue = this.placeholder;\n // },\n mounted: function mounted() {\n this.init();\n },\n\n methods: {\n closePicker: function closePicker(e) {\n if (e) e.preventDefault();\n this.show = false;\n },\n onCancelHandler: function onCancelHandler() {\n this.closePicker();\n if (typeof this.onCancel === 'function') {\n this.onCancel();\n }\n },\n onConfirmHandler: function onConfirmHandler() {\n var data = this.colsData;\n var cols = data.length;\n var pos = this.pos;\n var selected = [];\n var str = '';\n var strIds = '';\n if (this.isLong && this.pos[0].index === 0) {\n selected.push({\n name: IS_LONG,\n id: -1\n });\n strIds = '-1';\n str = IS_LONG;\n } else {\n var index = 0;\n var names = [];\n var ids = [];\n while (index < cols) {\n var _data$index$pos$index = data[index][pos[index].index],\n name = _data$index$pos$index.name,\n id = _data$index$pos$index.id;\n\n selected.push({\n name: name,\n id: id\n });\n ids.push(id);\n names.push(name);\n index += 1;\n }\n\n str = names.join(',');\n strIds = ids.join(',');\n if (this.date === 'date') {\n strIds = ids.join('-');\n str = str.replace(/,/g, '');\n } else if (this.date === 'time') {\n strIds = ids.join(':');\n str = str.replace(',', '');\n } else if (this.date === 'datetime') {\n strIds = strIds.replace(/(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)/g, '$1-$2-$3 $4:$5');\n str = str.replace(/(.+),(.+),(.+),(.+),(.+)/g, '$1$2$3 $4$5');\n }\n }\n if (typeof this.onConfirm === 'function') {\n this.onConfirm({\n str: str,\n strIds: strIds,\n obj: this.toJSON(selected),\n name: this.name\n });\n }\n\n this.$emit('input', strIds);\n this.show = false;\n this.pickerValue = str;\n },\n toJSON: function toJSON(data) {\n return JSON.parse(JSON.stringify(data));\n },\n setTransition: function setTransition(el, val) {\n el.style.transition = val;\n el.style.webkitTransition = val;\n },\n setTransform: function setTransform(el, val) {\n el.style.transform = val;\n el.style.webkitTransform = val;\n },\n dynamicStyle: function dynamicStyle(column) {\n var moveY = this.pos[column].moveY;\n var value = 'translate3d(0, ' + this.pos[column].moveY + 'px, 0)';\n if (typeof moveY === 'string' && moveY.indexOf('em') !== -1) {\n value = 'translate3d(0, ' + this.pos[column].moveY + ', 0)';\n }\n return {\n webkitTransform: value,\n transform: value\n };\n },\n setPosAttr: function setPosAttr(index, attr, val) {\n this.pos[index][attr] = val;\n },\n getScreenY: function getScreenY(e) {\n var type = e.type;\n var screenY = 0;\n if (type.indexOf('mouse') === 0) {\n screenY = e.screenY;\n } else {\n screenY = e.touches[0].screenY;\n }\n return screenY;\n },\n getColumn: function getColumn(el) {\n return +el.dataset.column;\n },\n moveTo: function moveTo(el, y) {\n var _this = this;\n\n var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.3;\n\n var currentColumn = this.pos[el.dataset.column];\n var moveY = currentColumn.moveY;\n if (moveY !== y) {\n currentColumn.moveY = y;\n if (time) {\n this.setTransition(el, 'cubic-bezier(0,0,0.2,1.15) ' + time + 's');\n }\n setTimeout(function () {\n _this.setTransition(el, '');\n }, time * 1000);\n }\n },\n\n /**\n * @param {number} column - 代表的列数(0, 1, 2);\n * @param {number} index - 当前列表,滚动到的行数索引\n */\n onChange: function onChange(column, index) {\n var currentColumn = this.colsData[column];\n var oldItem = currentColumn[this.pos[column].index];\n var colLen = this.colsData.length;\n if (index === this.pos[column].index) return;\n this.setPosAttr(column, 'index', index);\n var newItem = currentColumn[index];\n if (typeof this.onItemChange === 'function') {\n this.onItemChange(this.toJSON({\n oldItem: {\n name: oldItem.name,\n id: oldItem.id\n },\n newItem: {\n name: newItem.name,\n id: newItem.id\n }\n }));\n }\n // 这里要注意是级连的还是单独的\n if (this.date === 'date' || this.date === 'datetime') {\n var year = this.colsData[0][index];\n if (this.isLong && colLen > 1 && column === 0 && year && year.id === -1) {\n return this.isLongYear();\n } else {\n if (column === 0 && oldItem.id === -1) {\n if (colLen > 1) this.setMonths(0);\n if (colLen > 2) this.setDay(1);\n if (colLen === 5) {\n this.setHours(0);\n this.setMinutes(0);\n }\n }\n return this.setDateColumn(column, index);\n }\n } else if (this.date === 'time') {\n return this.setTimeColumn(column, index);\n }\n if (column >= 2 || this.pickerData.length > 1) return;\n var _currentColumn$index = currentColumn[index],\n id = _currentColumn$index.id,\n children = _currentColumn$index.children;\n\n if (id === -1) return;\n var noData = [{ name: this.placeholder, id: -1 }];\n if (this.cols === 3) this.resetColumn(2);\n if (column === 0) {\n if (this.cols > 1) {\n this.$set(this.colsData, 1, children || noData);\n this.resetColumn(1);\n }\n if (this.cols !== 3) return;\n if (children && children[0]) {\n this.$set(this.colsData, 2, children[0].children || noData);\n } else {\n this.$set(this.colsData, 2, noData);\n }\n } else if (column === 1 && this.cols === 3) {\n this.$set(this.colsData, 2, children || noData);\n }\n },\n onStart: function onStart(e) {\n e.preventDefault();\n var target = e.target;\n var children = target.children;\n if (!children || !children.length) return;\n var itemHeight = children[0].getBoundingClientRect().height;\n var len = children.length;\n var scrollHeight = itemHeight * (len - 1);\n var column = this.getColumn(target);\n var moveY = this.pos[column].moveY;\n // 如果初始化是取的默认值 moveY 的单位为 em,itemHeight === 2em;\n if (typeof moveY === 'string' && moveY.indexOf('em') !== -1) {\n moveY = parseInt(moveY) * (itemHeight / 2);\n }\n this.itemHeight = itemHeight;\n this.setPosAttr(column, 'startY', this.getScreenY(e));\n this.setPosAttr(column, 'moveY', moveY);\n this.setPosAttr(column, 'isMove', 1);\n this.setPosAttr(column, 'lastY', moveY);\n this.setPosAttr(column, 'scrollHeight', scrollHeight);\n this.setTransition(target, 'cubic-bezier(0, 0, 0.2, 1.15) 0s');\n },\n\n // 进行数据运算时,记得判断一下数值是否存在\n onMove: function onMove(e) {\n e.preventDefault();\n var target = e.target;\n var children = target.children;\n if (!children || !children.length) return;\n var column = this.getColumn(target);\n var currentY = this.getScreenY(e);\n var currentColumn = this.pos[column];\n var newMoveY = currentColumn.lastY - currentColumn.startY + currentY;\n var isMove = currentColumn.isMove;\n if (isMove) this.setPosAttr(column, 'moveY', newMoveY);\n },\n onEnd: function onEnd(e) {\n e.preventDefault();\n var target = e.target;\n var children = target.children;\n if (!children || !children.length) return;\n var column = this.getColumn(target);\n var currentPos = this.pos[column];\n var itemHeight = this.itemHeight;\n var scrollHeight = currentPos.scrollHeight;\n var targetY = currentPos.moveY;\n\n if (targetY % itemHeight !== 0) {\n targetY = Math.round(targetY / itemHeight) * itemHeight;\n }\n\n if (targetY > 0) {\n targetY = 0;\n } else if (Math.abs(targetY) > scrollHeight) {\n targetY = -scrollHeight;\n }\n var index = Math.abs(targetY / itemHeight);\n this.moveTo(target, targetY);\n this.onChange(column, index);\n this.setPosAttr(column, 'isMove', 0);\n },\n\n // 组件初始化数据\n init: function init() {\n var cols = +this.cols || 3;\n var index = 0;\n while (index < cols) {\n this.$set(this.pos, index, {\n startY: 0,\n moveY: 0,\n lastY: 0,\n index: 0,\n scrollHeight: 0,\n isMove: 0\n });\n index += 1;\n }\n\n if (this.date) {\n if (this.date.indexOf('date') !== -1 && this.isLong && +this.value === -1) {\n this.initLongDate();\n } else {\n this.initDate();\n }\n return;\n }\n if (this.pickerData.length > 1) {\n this.$set(this, 'colsData', this.pickerData);\n } else {\n this.colsData[0] = this.pickerData[0];\n if (cols > 1) {\n this.colsData[1] = this.pickerData[0][0].children || [];\n if (cols === 3) {\n this.colsData[2] = this.pickerData[0][0].children[0].children;\n }\n }\n }\n if (this.value || this.value === 0) {\n this.setDefaultValue(this.value);\n }\n },\n\n // 组件默认值(初始化从父组件传进来的)\n setDefaultValue: function setDefaultValue(value) {\n var _this2 = this;\n\n var defaultValue = value;\n if (typeof value === 'string') {\n defaultValue = value.split(',');\n } else if (typeof value === 'number') {\n defaultValue = [value];\n }\n var firstDefault = defaultValue[0];\n /**\n * isChildren 用来判断 picker 取值是级联(取上一列的children) 还是并联(取pickerData[index])\n */\n var isChildren = this.pickerData.length === 1;\n var defaultValueFn = function defaultValueFn(value, column) {\n if (!value && value !== 0) return;\n _this2.colsData[column].map(function (item, index) {\n if (item.name.toString() === value.toString() || item.id.toString() === value.toString()) {\n _this2.pos[column].index = index;\n _this2.pos[column].moveY = '-' + 2 * index + 'em';\n if (column === 0) {\n _this2.pickerValue = item.name;\n } else {\n _this2.pickerValue += ',' + item.name;\n }\n }\n });\n };\n defaultValueFn(firstDefault, 0);\n if (this.cols === 1) return;\n if (this.pickerData.length > 1) {\n this.$set(this, 'colsData', this.pickerData);\n }\n if (this.cols > 1) {\n if (isChildren) {\n this.colsData[1] = this.pickerData[0][this.pos[0].index].children || [];\n }\n var secondDefault = defaultValue[1];\n defaultValueFn(secondDefault, 1);\n if (this.cols === 3) {\n if (isChildren) {\n this.colsData[2] = this.pickerData[0][this.pos[0].index].children[this.pos[1].index].children;\n }\n var thirdDefault = defaultValue[2];\n defaultValueFn(thirdDefault, 2);\n }\n }\n },\n\n // 日期且默认值是长期有效时的初始化\n initLongDate: function initLongDate() {\n var now = new Date();\n this.pickerValue = IS_LONG;\n this.setYear(now.getFullYear(), true);\n if (this.cols > 1) this.colsData[1] = [];\n if (this.cols > 2) this.colsData[2] = [];\n if (this.date === 'datetime') {\n this.resetColumn(3);\n this.resetColumn(4);\n this.colsData[3] = [];\n this.colsData[4] = [];\n }\n },\n\n // 日期初始化\n initDate: function initDate() {\n var now = new Date();\n var strIds = this.value || '';\n if (strIds && this.date.indexOf('date') !== -1) {\n var reValue = strIds.replace(/(\\.|-)/g, '/');\n now = new Date(reValue);\n }\n if (now.toString().toLowerCase().indexOf('invalid') !== -1) {\n now = new Date();\n } else if (strIds) {\n var name = strIds.replace(/(\\.|\\/)/g, '-');\n if (this.date === 'date') {\n name = name.replace(/(\\d+)\\-?(\\d*)\\-?(\\d*)/g, function (match, p1, p2, p3) {\n var str = '';\n if (p1) {\n str += p1 + '\\u5E74';\n }\n if (p2) {\n str += p2 + '\\u6708';\n }\n if (p3) {\n str += p3 + '\\u65E5';\n }\n return str;\n });\n } else if (this.date === 'time') {\n var arr = strIds.split(':');\n if (arr && arr.length === 2) {\n name = arr[0].length === 1 ? '0' + arr[0] + '\\u65F6' : arr[0] + '\\u65F6';\n name += arr[1].length === 1 ? '0' + arr[1] + '\\u5206' : arr[1] + '\\u5206';\n }\n } else if (this.date === 'datetime') {\n name = name.replace(/(\\d+)\\-(\\d+)\\-(\\d+) (\\d+):(\\d+)/g, function (match, p1, p2, p3, p4, p5) {\n var str = p1 + '\\u5E74' + p2 + '\\u6708' + p3 + '\\u65E5 ';\n str += p4.length === 1 ? '0' + p4 + '\\u65F6' : p4 + '\\u65F6';\n str += p5.length === 1 ? '0' + p5 + '\\u5206' : p5 + '\\u5206';\n return str;\n });\n }\n this.pickerValue = name;\n }\n var nowYear = now.getFullYear();\n var nowMonths = now.getMonth();\n var nowDay = now.getDate();\n var nowHours = now.getHours();\n var nowMinutes = now.getMinutes();\n if (this.date === 'time') {\n if (this.value) {\n var times = this.value.split(':');\n this.setHours(this.toParseInt(times[0]));\n this.setMinutes(this.toParseInt(times[1]));\n } else {\n this.setHours(nowHours);\n this.setMinutes(nowMinutes);\n }\n } else {\n this.setYear(nowYear);\n if (this.cols > 1) {\n this.setMonths(nowMonths);\n if (this.cols > 2) {\n this.setDay(nowDay);\n this.setDateColumn(this.cols);\n }\n }\n if (this.date === 'datetime') {\n this.setHours(nowHours);\n this.setMinutes(nowMinutes);\n }\n }\n },\n toParseInt: function toParseInt(value) {\n var num = parseInt(value, 10);\n return Math.abs(num) || 0;\n },\n\n /**\n * @param {number} nowYear - 现在的年份\n * @param {boolean} type - true 说明是默认值为'长期有效'时进行的初始化\n */\n setYear: function setYear(nowYear, type) {\n var startYear = parseInt(this.minDate) || 1949;\n var endYear = parseInt(this.maxDate) || nowYear + 50;\n var year = startYear;\n var yearColumn = [];\n var index = nowYear - startYear;\n // 如果传了最小年份, 又传了默认值, 当默认值大于最小年份时, 直接设置索引为0\n if (index < 0) index = 0;\n // 判断是否增加 长期有效 (身份证有效期会使用到)\n if (this.isLong) {\n yearColumn.push({\n name: IS_LONG,\n id: -1\n });\n index += 1;\n }\n while (year <= endYear) {\n yearColumn.push({\n name: year + '\\u5E74',\n id: year\n });\n year += 1;\n }\n if (type) {\n this.pos[0].index = 0;\n this.pos[0].moveY = 0;\n } else {\n this.pos[0].index = index;\n this.pos[0].moveY = '-' + 2 * index + 'em';\n }\n this.colsData[0] = yearColumn;\n },\n setMonths: function setMonths(nowMonths) {\n var monthsColum = [];\n var months = 1;\n while (months <= 12) {\n monthsColum.push({\n name: months + '\\u6708',\n id: months\n });\n months += 1;\n }\n this.pos[1].index = nowMonths;\n this.pos[1].moveY = '-' + 2 * nowMonths + 'em';\n this.colsData[1] = monthsColum;\n },\n setDay: function setDay(nowDay) {\n var dayColum = [];\n var day = 1;\n while (day <= 31) {\n dayColum.push({\n name: day + '\\u65E5',\n id: day\n });\n day += 1;\n }\n this.pos[2].index = nowDay - 1;\n this.pos[2].moveY = '-' + 2 * (nowDay - 1) + 'em';\n this.colsData[2] = dayColum;\n },\n\n /**\n * 跟据年、月来控制日期的天数\n * @param {number} column - 代表的列数(0, 1, 2);\n * @param {number} index - 当前列表,滚动到的行数索引\n */\n setDateColumn: function setDateColumn(column, index) {\n if (this.cols < 3) return;\n var year = this.colsData[0][this.pos[0].index];\n var month = this.colsData[1][this.pos[1].index];\n var dayIndex = this.pos[2].index;\n var day = this.colsData[2][dayIndex];\n var isLeapYear = this.isLeapYear(year.id);\n if (column === 2) return;\n this.setDay(day.id);\n // 小月份,共 30 天\n if (month.id === 2) {\n if (isLeapYear) {\n this.colsData[2].splice(29, 2);\n if (dayIndex >= 29) {\n this.pos[2].moveY = -28 * this.itemHeight;\n this.pos[2].index = 28;\n }\n } else {\n this.colsData[2].splice(28, 3);\n if (dayIndex >= 28) {\n this.pos[2].moveY = -27 * this.itemHeight;\n this.pos[2].index = 27;\n }\n }\n } else if ([4, 6, 9, 11].indexOf(month.id) !== -1) {\n this.colsData[2].splice(30, 1);\n if (dayIndex === 30) {\n this.pos[2].moveY = -29 * this.itemHeight;\n this.pos[2].index = 29;\n }\n }\n },\n isLongYear: function isLongYear() {\n var colLen = this.colsData.length;\n this.colsData[1] = [];\n if (colLen > 2) {\n this.colsData[2] = [];\n }\n if (colLen === 5) {\n this.colsData[3] = [];\n this.colsData[4] = [];\n }\n },\n\n /**\n * 判断是否为闰年\n * 能被 400 整除 或 能被 4 整除但不能被 100 整除\n * @param {number} year - 当前年份\n */\n isLeapYear: function isLeapYear(year) {\n if (year % 400 === 0 || year % 4 === 0 && year % 100 !== 0) return true;\n return false;\n },\n setHours: function setHours(nowHours) {\n var hoursColum = [];\n var hours = 0;\n var column = this.date === 'time' ? 0 : 3;\n while (hours < 24) {\n hoursColum.push({\n name: ((hours + '').length === 1 ? '0' + hours : hours) + '\\u65F6',\n id: hours\n });\n hours += 1;\n }\n if (!this.pos[column]) {\n this.resetColumn(3);\n }\n this.pos[column].index = nowHours;\n this.pos[column].moveY = '-' + 2 * nowHours + 'em';\n this.colsData[column] = hoursColum;\n },\n setMinutes: function setMinutes(nowMinutes) {\n var minutesColum = [];\n var minutes = 0;\n var column = this.date === 'time' ? 1 : 4;\n while (minutes < 60) {\n minutesColum.push({\n name: ((minutes + '').length === 1 ? '0' + minutes : minutes) + '\\u5206',\n id: minutes\n });\n minutes += 1;\n }\n if (!this.pos[column]) {\n this.resetColumn(4);\n }\n this.pos[column].index = nowMinutes;\n this.pos[column].moveY = '-' + 2 * nowMinutes + 'em';\n this.colsData[column] = minutesColum;\n },\n setTimeColumn: function setTimeColumn(column, index) {\n console.log(column, index);\n },\n\n /**\n * @param {number} column - 当前的列数\n **/\n resetColumn: function resetColumn(column) {\n this.$set(this.pos, column, {\n startY: 0,\n moveY: 0,\n lastY: 0,\n index: 0,\n isMove: 0\n });\n }\n }\n};\n\n//# sourceURL=webpack:///./src/picker.vue?./node_modules/babel-loader/lib??ref--1!./node_modules/vue-loader/lib??vue-loader-options"); 98 | 99 | /***/ }), 100 | 101 | /***/ "./node_modules/css-loader/index.js?!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib/index.js?!./node_modules/less-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js?!./src/picker.vue?vue&type=style&index=0&id=f6db32b2&lang=less&scoped=true": 102 | /*!*******************************************************************************************************************************************************************************************************************************************************************************************************************!*\ 103 | !*** ./node_modules/css-loader??ref--2-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--2-2!./node_modules/less-loader/dist/cjs.js!./node_modules/vue-loader/lib??vue-loader-options!./src/picker.vue?vue&type=style&index=0&id=f6db32b2&lang=less&scoped=true ***! 104 | \*******************************************************************************************************************************************************************************************************************************************************************************************************************/ 105 | /*! no static exports found */ 106 | /***/ (function(module, exports, __webpack_require__) { 107 | 108 | eval("exports = module.exports = __webpack_require__(/*! ../node_modules/css-loader/lib/css-base.js */ \"./node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.i, \"\\n.vue-ios-pickers[data-v-f6db32b2] {\\n width: 100%;\\n}\\n.picker-value[data-v-f6db32b2] {\\n padding: 0.5em 1em 0.5em 0;\\n height: 1.2em;\\n position: relative;\\n -webkit-box-sizing: content-box;\\n box-sizing: content-box;\\n}\\n.picker-value input[data-v-f6db32b2] {\\n -webkit-box-sizing: border-box;\\n box-sizing: border-box;\\n text-align: right;\\n pointer-events: none;\\n position: absolute;\\n left: 0;\\n top: 0;\\n width: 100%;\\n height: 100%;\\n margin: 0;\\n padding: 0 1.2em 0 0;\\n border: 0 none;\\n font: inherit;\\n background: transparent;\\n}\\n.picker-value[data-v-f6db32b2]:after {\\n content: '';\\n position: absolute;\\n right: 0.2em;\\n top: 0;\\n bottom: 0;\\n margin: auto;\\n width: 0.7em;\\n height: 0.7em;\\n border-top: 1px solid #999;\\n border-right: 1px solid #999;\\n -webkit-transform: rotateZ(45deg);\\n -ms-transform: rotate(45deg);\\n transform: rotateZ(45deg);\\n}\\n.picker-mask[data-v-f6db32b2] {\\n position: fixed;\\n top: 0;\\n left: 0;\\n right: 0;\\n bottom: 0;\\n height: 100%;\\n background-color: rgba(0, 0, 0, 0.4);\\n z-index: 999;\\n}\\n.picker-wrapper[data-v-f6db32b2] {\\n background-color: #fff;\\n color: #333;\\n width: 100%;\\n position: fixed;\\n left: 0;\\n bottom: 0;\\n z-index: 1000;\\n overflow: hidden;\\n -webkit-transition: all 0.3s ease;\\n -o-transition: all 0.3s ease;\\n transition: all 0.3s ease;\\n}\\n.btn-box[data-v-f6db32b2] {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-pack: justify;\\n -ms-flex-pack: justify;\\n justify-content: space-between;\\n -webkit-box-align: stretch;\\n -ms-flex-align: stretch;\\n align-items: stretch;\\n background-color: #fff;\\n border-top: 1px solid #ececec;\\n border-bottom: 1px solid #ececec;\\n}\\n.btn[data-v-f6db32b2] {\\n text-decoration: none;\\n color: #0575f2;\\n padding: 0.6em;\\n}\\n.data-box[data-v-f6db32b2] {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n position: relative;\\n}\\n.data-box .scroll-mask[data-v-f6db32b2] {\\n position: absolute;\\n left: 0;\\n top: 0;\\n z-index: 1;\\n width: 100%;\\n height: 100%;\\n background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(rgba(255, 255, 255, 0.6))), -webkit-gradient(linear, left bottom, left top, from(#ffffff), to(rgba(255, 255, 255, 0.6)));\\n background-image: -o-linear-gradient(top, #ffffff, rgba(255, 255, 255, 0.6)), -o-linear-gradient(bottom, #ffffff, rgba(255, 255, 255, 0.6));\\n background-image: linear-gradient(180deg, #ffffff, rgba(255, 255, 255, 0.6)), linear-gradient(0deg, #ffffff, rgba(255, 255, 255, 0.6));\\n background-position: top, bottom;\\n background-size: 100% 6em;\\n background-repeat: no-repeat;\\n pointer-events: none;\\n}\\n.data-box .items[data-v-f6db32b2] {\\n -webkit-box-flex: 1;\\n -ms-flex: 1;\\n flex: 1;\\n font-size: 1em;\\n height: 14em;\\n position: relative;\\n overflow: hidden;\\n}\\n.data-box .item[data-v-f6db32b2] {\\n height: 2em;\\n line-height: 2em;\\n text-align: center;\\n overflow: hidden;\\n white-space: nowrap;\\n pointer-events: none;\\n}\\n.data-box .border[data-v-f6db32b2] {\\n height: 2em;\\n width: 100%;\\n border-top: 1px solid #d3d3d3;\\n border-bottom: 1px solid #d3d3d3;\\n position: absolute;\\n left: 0;\\n top: 6em;\\n z-index: 2;\\n pointer-events: none;\\n}\\n.data-box .scroll[data-v-f6db32b2] {\\n position: absolute;\\n left: 0;\\n top: 0;\\n width: 100%;\\n padding-top: 6em;\\n padding-bottom: 6em;\\n margin-top: 0;\\n list-style: none;\\n padding-left: 0;\\n}\\n\", \"\"]);\n\n// exports\n\n\n//# sourceURL=webpack:///./src/picker.vue?./node_modules/css-loader??ref--2-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--2-2!./node_modules/less-loader/dist/cjs.js!./node_modules/vue-loader/lib??vue-loader-options"); 109 | 110 | /***/ }), 111 | 112 | /***/ "./node_modules/css-loader/lib/css-base.js": 113 | /*!*************************************************!*\ 114 | !*** ./node_modules/css-loader/lib/css-base.js ***! 115 | \*************************************************/ 116 | /*! no static exports found */ 117 | /***/ (function(module, exports, __webpack_require__) { 118 | 119 | "use strict"; 120 | eval("\n\n/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function (useSourceMap) {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\treturn this.map(function (item) {\n\t\t\tvar content = cssWithMappingToString(item, useSourceMap);\n\t\t\tif (item[2]) {\n\t\t\t\treturn \"@media \" + item[2] + \"{\" + content + \"}\";\n\t\t\t} else {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}).join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function (modules, mediaQuery) {\n\t\tif (typeof modules === \"string\") modules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor (var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif (typeof id === \"number\") alreadyImportedModules[id] = true;\n\t\t}\n\t\tfor (i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif (typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif (mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if (mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n\tvar content = item[1] || '';\n\tvar cssMapping = item[3];\n\tif (!cssMapping) {\n\t\treturn content;\n\t}\n\n\tif (useSourceMap && typeof btoa === 'function') {\n\t\tvar sourceMapping = toComment(cssMapping);\n\t\tvar sourceURLs = cssMapping.sources.map(function (source) {\n\t\t\treturn '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */';\n\t\t});\n\n\t\treturn [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n\t}\n\n\treturn [content].join('\\n');\n}\n\n// Adapted from convert-source-map (MIT)\nfunction toComment(sourceMap) {\n\t// eslint-disable-next-line no-undef\n\tvar base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n\tvar data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;\n\n\treturn '/*# ' + data + ' */';\n}\n\n//# sourceURL=webpack:///./node_modules/css-loader/lib/css-base.js?"); 121 | 122 | /***/ }), 123 | 124 | /***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./src/picker.vue?vue&type=template&id=f6db32b2&scoped=true": 125 | /*!************************************************************************************************************************************************************************************************!*\ 126 | !*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./src/picker.vue?vue&type=template&id=f6db32b2&scoped=true ***! 127 | \************************************************************************************************************************************************************************************************/ 128 | /*! exports provided: render, staticRenderFns */ 129 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 130 | 131 | "use strict"; 132 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"vue-ios-pickers\" },\n [\n _c(\n \"div\",\n {\n staticClass: \"picker-value\",\n on: {\n click: function($event) {\n _vm.show = true\n }\n }\n },\n [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.pickerValue,\n expression: \"pickerValue\"\n }\n ],\n style: { textAlign: _vm.align },\n attrs: { placeholder: _vm.placeholder },\n domProps: { value: _vm.pickerValue },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.pickerValue = $event.target.value\n }\n }\n })\n ]\n ),\n _vm._v(\" \"),\n _vm.show\n ? _c(\"transition\", { attrs: { name: \"picker\" } }, [\n _c(\"div\", [\n _c(\"div\", {\n key: \"mask\",\n staticClass: \"picker-mask\",\n on: { click: _vm.closePicker, mouseup: _vm.closePicker }\n }),\n _vm._v(\" \"),\n _c(\"div\", { key: \"wrapper\", staticClass: \"picker-wrapper\" }, [\n _c(\"div\", { staticClass: \"btn-box\" }, [\n _c(\n \"a\",\n {\n staticClass: \"btn btn-cancel\",\n on: { click: _vm.onCancelHandler }\n },\n [_vm._v(\"取消\")]\n ),\n _vm._v(\" \"),\n _c(\n \"a\",\n {\n staticClass: \"btn btn-confirm\",\n on: { click: _vm.onConfirmHandler }\n },\n [_vm._v(\"确定\")]\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"div\",\n { staticClass: \"data-box\" },\n [\n _c(\"div\", { staticClass: \"scroll-mask\" }),\n _vm._v(\" \"),\n _vm._l(_vm.colsData, function(column, index) {\n return _c(\"div\", { key: index, staticClass: \"items\" }, [\n _c(\n \"ul\",\n {\n staticClass: \"scroll\",\n style: _vm.dynamicStyle(index),\n attrs: {\n \"data-column\": index,\n \"data-event\": column.length > 0\n },\n on: {\n touchstart: _vm.onStart,\n mousedown: _vm.onStart,\n touchmove: _vm.onMove,\n mousemove: _vm.onMove,\n touchend: _vm.onEnd,\n mouseup: _vm.onEnd\n }\n },\n _vm._l(column, function(item, index) {\n return _c(\"li\", {\n key: index,\n staticClass: \"item\",\n domProps: { textContent: _vm._s(item.name) }\n })\n })\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"border\" })\n ])\n })\n ],\n 2\n )\n ])\n ])\n ])\n : _vm._e()\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./src/picker.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options"); 133 | 134 | /***/ }), 135 | 136 | /***/ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js": 137 | /*!********************************************************************!*\ 138 | !*** ./node_modules/vue-loader/lib/runtime/componentNormalizer.js ***! 139 | \********************************************************************/ 140 | /*! exports provided: default */ 141 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 142 | 143 | "use strict"; 144 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return normalizeComponent; });\n/* globals __VUE_SSR_CONTEXT__ */\n\n// IMPORTANT: Do NOT use ES2015 features in this file (except for modules).\n// This module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle.\n\nfunction normalizeComponent (\n scriptExports,\n render,\n staticRenderFns,\n functionalTemplate,\n injectStyles,\n scopeId,\n moduleIdentifier, /* server only */\n shadowMode /* vue-cli only */\n) {\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (render) {\n options.render = render\n options.staticRenderFns = staticRenderFns\n options._compiled = true\n }\n\n // functional template\n if (functionalTemplate) {\n options.functional = true\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = 'data-v-' + scopeId\n }\n\n var hook\n if (moduleIdentifier) { // server build\n hook = function (context) {\n // 2.3 injection\n context =\n context || // cached call\n (this.$vnode && this.$vnode.ssrContext) || // stateful\n (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional\n // 2.2 with runInNewContext: true\n if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {\n context = __VUE_SSR_CONTEXT__\n }\n // inject component styles\n if (injectStyles) {\n injectStyles.call(this, context)\n }\n // register component module identifier for async chunk inferrence\n if (context && context._registeredComponents) {\n context._registeredComponents.add(moduleIdentifier)\n }\n }\n // used by ssr in case component is cached and beforeCreate\n // never gets called\n options._ssrRegister = hook\n } else if (injectStyles) {\n hook = shadowMode\n ? function () { injectStyles.call(this, this.$root.$options.shadowRoot) }\n : injectStyles\n }\n\n if (hook) {\n if (options.functional) {\n // for template-only hot-reload because in that case the render fn doesn't\n // go through the normalizer\n options._injectStyles = hook\n // register for functioal component in vue file\n var originalRender = options.render\n options.render = function renderWithStyleInjection (h, context) {\n hook.call(context)\n return originalRender(h, context)\n }\n } else {\n // inject component registration as beforeCreate hook\n var existing = options.beforeCreate\n options.beforeCreate = existing\n ? [].concat(existing, hook)\n : [hook]\n }\n }\n\n return {\n exports: scriptExports,\n options: options\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/vue-loader/lib/runtime/componentNormalizer.js?"); 145 | 146 | /***/ }), 147 | 148 | /***/ "./node_modules/vue-style-loader/index.js!./node_modules/css-loader/index.js?!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib/index.js?!./node_modules/less-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js?!./src/picker.vue?vue&type=style&index=0&id=f6db32b2&lang=less&scoped=true": 149 | /*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\ 150 | !*** ./node_modules/vue-style-loader!./node_modules/css-loader??ref--2-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--2-2!./node_modules/less-loader/dist/cjs.js!./node_modules/vue-loader/lib??vue-loader-options!./src/picker.vue?vue&type=style&index=0&id=f6db32b2&lang=less&scoped=true ***! 151 | \***************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ 152 | /*! no static exports found */ 153 | /***/ (function(module, exports, __webpack_require__) { 154 | 155 | eval("// style-loader: Adds some css to the DOM by adding a 35 | 36 | 37 |
38 | 122 |
123 |

124 |     
125 |
126 | 127 | 128 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-ios-pickers", 3 | "version": "1.4.11", 4 | "description": "基于vue,iOS风格的picker组件,支持三级联动,日期(年.月.日),时间(时:分),日期+时间,年,年+月", 5 | "main": "./src/index.es5.js", 6 | "repository": "https://github.com/YuanWing/vue-ios-pickers", 7 | "keywords": [ 8 | "vue", 9 | "picker", 10 | "date", 11 | "time", 12 | "datetime", 13 | "vue-picker", 14 | "ios-picker" 15 | ], 16 | "author": "音十 ", 17 | "license": "MIT", 18 | "scripts": { 19 | "dev": "webpack --mode=development", 20 | "build": "webpack --mode=production" 21 | }, 22 | "dependencies": { 23 | "vue": "^2.5.16" 24 | }, 25 | "devDependencies": { 26 | "webpack": "^4.16.1", 27 | "webpack-cli": "^3.0.8", 28 | "autoprefixer": "^8.6.5", 29 | "babel-core": "^6.26.3", 30 | "babel-loader": "^7.1.5", 31 | "babel-preset-env": "^1.7.0", 32 | "css-loader": "^1.0.0", 33 | "html-webpack-plugin": "^3.2.0", 34 | "less": "^3.7.1", 35 | "less-loader": "^4.1.0", 36 | "postcss-loader": "^2.1.6", 37 | "vue-loader": "^15.2.4", 38 | "vue-style-loader": "^4.1.0", 39 | "vue-template-compiler": "^2.5.16" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /qrCode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuanWing/vue-ios-pickers/e547b0b5a6f47ccc07571009da45cde5409772bf/qrCode.png -------------------------------------------------------------------------------- /src/index.es5.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _picker = require('./picker.es5.vue'); 8 | 9 | var _picker2 = _interopRequireDefault(_picker); 10 | 11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 12 | 13 | var VueIosPickers = { 14 | install: function install(Vue) { 15 | Vue.component(_picker2.default.name, _picker2.default); 16 | } 17 | }; 18 | 19 | if (typeof window !== 'undefined' && window.Vue) { 20 | Vue.use(VueIosPickers); 21 | } 22 | 23 | exports.default = VueIosPickers; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Picker from './picker.vue'; 2 | 3 | var VueIosPickers = { 4 | install: function(Vue) { 5 | Vue.component(Picker.name, Picker); 6 | } 7 | }; 8 | 9 | if (typeof window !== 'undefined' && window.Vue) { 10 | Vue.use(VueIosPickers); 11 | } 12 | 13 | export default VueIosPickers; 14 | -------------------------------------------------------------------------------- /src/picker.es5.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 731 | 732 | 862 | -------------------------------------------------------------------------------- /src/picker.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 702 | 703 | 833 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const autoprefixer = require('autoprefixer'); 3 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 4 | module.exports = (env, argv) =>{ 5 | const mode = argv.mode === 'production'; 6 | return { 7 | entry: './src/index.js', 8 | output: { 9 | filename: `vue-ios-pickers${mode ? '.min' : ''}.js`, 10 | path: path.resolve(__dirname, 'dist') 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.vue$/, 16 | loader: 'vue-loader', 17 | }, { 18 | test: /\.js$/, 19 | loader: 'babel-loader', 20 | options: { 21 | presets: [['env']] 22 | } 23 | }, { 24 | test: /\.less$/, 25 | use: [ 26 | 'vue-style-loader', 27 | { 28 | loader: 'css-loader', 29 | options: { 30 | importLoaders: 2 31 | } 32 | }, 33 | { 34 | loader: 'postcss-loader', 35 | options: { 36 | plugins: [ 37 | autoprefixer({ 38 | browsers: ['last 3 versions'] 39 | }) 40 | ] 41 | }, 42 | }, 43 | 'less-loader' 44 | ] 45 | } 46 | ] 47 | }, 48 | plugins: [ 49 | new VueLoaderPlugin() 50 | ] 51 | } 52 | }; 53 | --------------------------------------------------------------------------------