├── .DS_Store
├── .gitignore
├── LICENSE
├── README-en.md
├── README.md
├── city-data.js
├── dist
├── index.js
└── picker.esm.js
├── example
├── .DS_Store
├── css
│ └── app.279fbbfe.css
├── favicon.ico
├── index.html
└── js
│ ├── app.5d01ef29.js
│ └── chunk-vendors.0ee7c3c1.js
├── index.js
├── lib
└── vue-picker.js
├── package.json
├── rollup.config.js
├── src
├── city-data.js
├── header.vue
├── index.js
├── index.vue
├── list.vue
├── picker.vue
├── render.js
└── utils.js
├── webpack.config.js
└── yarn.lock
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naihe138/vue-picker/2aed086132dc327206cd19a9f67d1de8f1532500/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2017] [naihe138]
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.
--------------------------------------------------------------------------------
/README-en.md:
--------------------------------------------------------------------------------
1 | English | [中文](https://github.com/naihe138/vue-picker)
2 |
3 | A picker componemt for vue2.0
4 | ------
5 | ![vue-pick.gif][1]
6 |
7 |
8 | ## Demo
9 |
10 | [https://naihe138.github.io/vue-picker/index.html][3]
11 |
12 |
13 | ## Install
14 |
15 | `npm install vue-pickers --save` or `yarn add vue-pickers`
16 |
17 | ## Use
18 |
19 | ````javascript
20 |
21 |
22 | show picker
23 |
29 |
30 |
31 |
32 |
67 | ````
68 |
69 | ## Attributes
70 |
71 | Attribute | Description | require | Type | Default
72 | ---- | --- | --- | --- | ---
73 | visible | show/hide picker | yes | Boolean | false
74 | data | pickerData,colums[data1, data2] | yes | Array | []
75 | layer | linkage column | no | Number | 0
76 | defaultIndex | default index | no | Number/Array(for more colums) | 无
77 | cancelText | cancel text | no | String | '取消'
78 | confirmText | confirm text | no | String | '确认'
79 | title | picker title | no | String | ''
80 | showToolbar | show toolbar | no | Boolean | false
81 | maskClick | click mask | no | Boolean | false
82 | itemHeight | height of each row | no | Number, String | '44px'
83 | rowNumber | how many lines to display (singular number recommended) | no | Number | 5
84 | appendToBody | Insert into body | no | Boolean | false
85 |
86 | ## Events
87 |
88 | Event Name | Description | require | Type | Default
89 | ---- | --- | --- | --- | ---
90 | change | select change | no | function(val) | -
91 | cancel | cancel button click | no | function | -
92 | confirm | confirm button click | no | function(val) | -
93 |
94 |
95 | [1]: http://ypimg.naice.me/vue-picker.gif
96 | [3]: https://naihe138.github.io/vue-picker/index.html
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 中文 | [English](https://github.com/naihe138/vue-picker/blob/master/README-en.md)
2 |
3 |
4 | `vue-picker`的组件,囊括了(`普通选择`、`联动选择`、`中国地址选择`)等等常见的picker,兼容PC、移动端,通过简单配置就可以出现一个强大的picker,感受下效果图。
5 |
6 |
7 | ![vue-pick.gif][1]
8 |
9 |
10 | ## Demo(快点去复制代码体验一波吧)
11 |
12 | [https://naihe138.github.io/vue-picker/index.html][3]
13 |
14 |
15 | ## Install
16 |
17 | `npm install vue-pickers --save` or `yarn add vue-pickers`
18 |
19 |
20 | ## 使用
21 |
22 | > 普通网页开发直接复制lib/vue-picker.js文件夹到项目即可直接使用
23 |
24 | ````javascript
25 |
26 |
27 | show picker
28 |
34 |
35 |
36 |
37 |
72 | ````
73 |
74 | ## 属性参数说明
75 |
76 | 参数 | 说明 | 是否必须 | 类型 |默认值
77 | ---- | --- | --- | --- | ---
78 | visible | 显示/隐藏picker | 是 | Boolean | false
79 | data | pickerData,多列[data1, data2] | 是 | Array | []
80 | layer | 联动显示列数 | 否 | Number | 0
81 | defaultIndex | 默认显示的index | 否 | Number/Array(多列用数组) | 无
82 | cancelText | 取消按钮文字 | 否 | String | '取消'
83 | confirmText | 去确认按钮文字 | 否 | String | '确认'
84 | title | picker标题 | 否 | String | ''
85 | showToolbar | 显示头部 | 否 | Boolean | false
86 | maskClick | 遮罩层是否可以点击关闭 | 否 | Boolean | false
87 | itemHeight | 每一行的高度 | 否 | Number, String | '44px'
88 | rowNumber | 显示多少行(建议单数) | 否 | Number | 5
89 | appendToBody | 是否插入到body中 | 否 | Boolean | false
90 |
91 | ## 事件说明
92 |
93 | 参数 | 说明 | 是否必须 | 类型 |默认值
94 | ---- | --- | --- | --- | ---
95 | change | 数据变化事件 | 否 | function(val) | 无
96 | cancel | 取消选择 | 否 | function | 无
97 | confirm | 确认选择 | 否 | function(val) | 无
98 |
99 |
100 | [1]: http://ypimg.naice.me/vue-picker.gif
101 | [3]: https://naihe138.github.io/vue-picker/index.html
102 |
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | import Picker from './picker.esm.js'
3 |
4 | if (typeof window !== 'undefined' && window.Vue) {
5 | window.Vue.component('vue-picker', Picker)
6 | }
7 |
8 | Picker.install = function(Vue){
9 | Vue.component(Picker.name, Picker)
10 | }
11 |
12 | export default Picker
13 |
--------------------------------------------------------------------------------
/dist/picker.esm.js:
--------------------------------------------------------------------------------
1 | import { normalizeComponent, createInjector } from 'vue-runtime-helpers';
2 |
3 | //
4 | //
5 | //
6 | //
7 | //
8 | //
9 | //
10 | //
11 | //
12 | //
13 | //
14 | //
15 |
16 | // TODO: 支持自定义的render渲染
17 | // import textRender from './render'
18 | var script = {
19 | props: {
20 | cancelText: {
21 | type: String
22 | },
23 | confirmText: {
24 | type: String
25 | },
26 | title: {
27 | type: String
28 | }
29 | },
30 | methods: {
31 | cancel () {
32 | this.$emit('cancel');
33 | },
34 | confirm () {
35 | this.$emit('confirm');
36 | }
37 | }
38 | };
39 |
40 | /* script */
41 | const __vue_script__ = script;
42 |
43 | /* template */
44 | var __vue_render__ = function() {
45 | var _vm = this;
46 | var _h = _vm.$createElement;
47 | var _c = _vm._self._c || _h;
48 | return _c("div", { staticClass: "header" }, [
49 | _c("div", { staticClass: "left" }, [
50 | _c("span", { staticClass: "btn", on: { click: _vm.cancel } }, [
51 | _vm._v(_vm._s(_vm.cancelText))
52 | ])
53 | ]),
54 | _vm._v(" "),
55 | _c("div", { staticClass: "title" }, [_vm._v(_vm._s(_vm.title))]),
56 | _vm._v(" "),
57 | _c("div", { staticClass: "right" }, [
58 | _c("span", { staticClass: "btn", on: { click: _vm.confirm } }, [
59 | _vm._v(_vm._s(_vm.confirmText))
60 | ])
61 | ])
62 | ])
63 | };
64 | var __vue_staticRenderFns__ = [];
65 | __vue_render__._withStripped = true;
66 |
67 | /* style */
68 | const __vue_inject_styles__ = function (inject) {
69 | if (!inject) return
70 | inject("data-v-6ffe26b0_0", { source: ".header[data-v-6ffe26b0] {\n height: 44px;\n line-height: 44px;\n display: -webkit-box;\n display: flex;\n -webkit-box-pack: justify;\n justify-content: space-between;\n position: relative;\n}\n.header[data-v-6ffe26b0]::after {\n position: absolute;\n box-sizing: border-box;\n content: \" \";\n pointer-events: none;\n top: -50%;\n right: -50%;\n bottom: -50%;\n left: -50%;\n border: 0 solid #ebedf0;\n -webkit-transform: scale(0.5);\n transform: scale(0.5);\n border-width: 1px 0;\n}\n.title[data-v-6ffe26b0] {\n max-width: 50%;\n font-weight: 500;\n font-size: 16px;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.btn[data-v-6ffe26b0] {\n padding: 0 16px;\n color: #1989fa;\n font-size: 14px;\n background-color: transparent;\n}\n\n/*# sourceMappingURL=header.vue.map */", map: {"version":3,"sources":["/Users/naice/my-project/vue-picker/src/header.vue","header.vue"],"names":[],"mappings":"AAuCA;EACA,YAAA;EACA,iBAAA;EACA,oBAAA;EAAA,aAAA;EACA,yBAAA;UAAA,8BAAA;EACA,kBAAA;ACtCA;ADuCA;EACA,kBAAA;EACA,sBAAA;EACA,YAAA;EACA,oBAAA;EACA,SAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,uBAAA;EACA,6BAAA;UAAA,qBAAA;EACA,mBAAA;ACrCA;ADwCA;EACA,cAAA;EACA,gBAAA;EACA,eAAA;EACA,kBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;ACrCA;ADuCA;EACA,eAAA;EACA,cAAA;EACA,eAAA;EACA,6BAAA;ACpCA;;AAEA,qCAAqC","file":"header.vue","sourcesContent":["\n \n \n\n\n\n\n",".header {\n height: 44px;\n line-height: 44px;\n display: flex;\n justify-content: space-between;\n position: relative;\n}\n.header::after {\n position: absolute;\n box-sizing: border-box;\n content: \" \";\n pointer-events: none;\n top: -50%;\n right: -50%;\n bottom: -50%;\n left: -50%;\n border: 0 solid #ebedf0;\n transform: scale(0.5);\n border-width: 1px 0;\n}\n\n.title {\n max-width: 50%;\n font-weight: 500;\n font-size: 16px;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.btn {\n padding: 0 16px;\n color: #1989fa;\n font-size: 14px;\n background-color: transparent;\n}\n\n/*# sourceMappingURL=header.vue.map */"]}, media: undefined });
71 |
72 | };
73 | /* scoped */
74 | const __vue_scope_id__ = "data-v-6ffe26b0";
75 | /* module identifier */
76 | const __vue_module_identifier__ = undefined;
77 | /* functional template */
78 | const __vue_is_functional_template__ = false;
79 | /* style inject SSR */
80 |
81 | /* style inject shadow dom */
82 |
83 |
84 |
85 | var Header = normalizeComponent(
86 | { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
87 | __vue_inject_styles__,
88 | __vue_script__,
89 | __vue_scope_id__,
90 | __vue_is_functional_template__,
91 | __vue_module_identifier__,
92 | false,
93 | createInjector,
94 | undefined,
95 | undefined
96 | );
97 |
98 | const DEFTAULT_ITEM_HEIGHT = 44;
99 |
100 | // 兼容pc 移动端
101 | const HAS_TOUCH = 'ontouchstart' in window;
102 | const START_EVENT = HAS_TOUCH ? 'touchstart' : 'mousedown';
103 | const MOVE_EVENT = HAS_TOUCH ? 'touchmove' : 'mousemove';
104 | const END_EVENT = HAS_TOUCH ? 'touchend' : 'mouseup';
105 |
106 | const getClient = e => {
107 | let clientX = HAS_TOUCH ? e.changedTouches[0].clientX : e.clientX;
108 | let clientY = HAS_TOUCH ? e.changedTouches[0].clientY : e.clientY;
109 | return {
110 | x: clientX,
111 | y: clientY
112 | }
113 | };
114 | const isPC = () => {
115 | const userAgentInfo = navigator.userAgent;
116 | const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
117 | let flag = true;
118 | for (var v = 0; v < Agents.length; v++) {
119 | if (userAgentInfo.indexOf(Agents[v]) > 0) {
120 | flag = false;
121 | break
122 | }
123 | }
124 | return flag
125 | };
126 |
127 | //
128 | const DEFAULT_DURATION = 200;
129 | // 惯性滑动思路:
130 | // 在手指离开屏幕时,如果和上一次 move 时的间隔小于 `LIMIT_TIME` 且 move
131 | // 距离大于 `LIMIT_DISTANCE` 时,执行惯性滑动
132 | const LIMIT_TIME = 300;
133 | const LIMIT_DISTANCE = 15;
134 | const IS_PC = isPC();
135 | var script$1 = {
136 | props: {
137 | defaultIndex: {
138 | type: Number,
139 | default: 0
140 | },
141 | column: {
142 | type: Array,
143 | default: () => ([])
144 | },
145 | boxHeight: Number,
146 | itemHeight: Number,
147 | rowNumber: Number
148 | },
149 | data() {
150 | return {
151 | ulStyle: {
152 | transform: `translate3d(0px, 0px, 0px)`,
153 | transitionDuration: `0ms`,
154 | transitionProperty: `none`,
155 | lineHeight: `${this.itemHeight}px`
156 | }
157 | }
158 | },
159 | computed: {
160 | count() {
161 | return this.column.length
162 | },
163 | getRoNumber() {
164 | return Math.floor(this.rowNumber / 2)
165 | }
166 | },
167 | methods: {
168 | init () {
169 | this.setTop(this.defaultIndex);
170 | const halfBox = (this.boxHeight - this.itemHeight) / 2;
171 | this.bottom = halfBox + this.itemHeight;
172 | this.top = halfBox - this.count * this.itemHeight;
173 | },
174 | // 根据index 设置滚动位置
175 | setTop (index = 0) {
176 | const { boxHeight, itemHeight } = this;
177 | this.startTop = ((boxHeight - itemHeight) / 2) - (index * itemHeight);
178 | this.ulStyle.transform = `translate3d(0px, ${this.startTop}px, 0px)`;
179 | this.selectIndex = index;
180 | this.change();
181 | },
182 | handleStart (e) {
183 | this.distStartTop = getClient(e).y;
184 | this.touchStartTime = Date.now();
185 | // ----
186 | this.startY = getClient(e).y;
187 | this.momentumTop = this.startTop;
188 |
189 | this.ulStyle.transitionDuration = `0ms`;
190 | this.ulStyle.transitionProperty = `none`;
191 | if (IS_PC) {
192 | document.addEventListener(MOVE_EVENT, this.handleMove, false);
193 | document.addEventListener(END_EVENT, this.handleEnd, false);
194 | }
195 | },
196 | handleMove (e) {
197 | e.preventDefault();
198 | e.stopPropagation();
199 | this.disY = getClient(e).y - this.startY;
200 | this.startY = getClient(e).y;
201 | if (this.startTop >= this.bottom) {
202 | this.startTop = this.bottom;
203 | } else if (this.startTop <= this.top) {
204 | this.startTop = this.top;
205 | } else {
206 | this.startTop += this.disY;
207 | }
208 | this.ulStyle.transform = `translate3d(0px, ${this.startTop}px, 0px)`;
209 | const now = Date.now();
210 |
211 | if (now - this.touchStartTime > LIMIT_TIME) {
212 | this.touchStartTime = now;
213 | this.momentumTop = this.startTop;
214 | }
215 | },
216 | handleEnd () {
217 | if (IS_PC) {
218 | document.removeEventListener(MOVE_EVENT, this.handleMove, false);
219 | document.removeEventListener(END_EVENT, this.handleEnd, false);
220 | }
221 | const distance = this.startTop - this.momentumTop;
222 | const duration = Date.now() - this.touchStartTime;
223 | const allowMomentum = duration < LIMIT_TIME && Math.abs(distance) > LIMIT_DISTANCE;
224 | if (allowMomentum) {
225 | this.toMove(distance, duration);
226 | } else {
227 | this.setTranfromTop();
228 | }
229 | },
230 | setTranfromTop () {
231 | this.ulStyle.transitionProperty = `all`;
232 | this.ulStyle.transitionDuration = `${DEFAULT_DURATION}ms`;
233 | if (this.startTop >= this.bottom - this.itemHeight) {
234 | this.setTop();
235 | } else if (this.startTop <= this.top + this.itemHeight) {
236 | this.setTop(this.count - 1);
237 | } else {
238 | let index = Math.round((this.startTop) / this.itemHeight);
239 | this.startTop = index * this.itemHeight;
240 | if (this.startTop > this.bottom) {
241 | this.startTop = this.bottom - this.itemHeight;
242 | index = -this.getRoNumber;
243 | } else if (this.startTop < this.top) {
244 | this.startTop = this.top + this.itemHeight;
245 | index = this.count + 1;
246 | }
247 | this.ulStyle.transform = `translate3d(0px, ${this.startTop}px, 0px)`;
248 | index = this.getRoNumber - index;
249 | if (this.selectIndex !== index) {
250 | this.selectIndex = index;
251 | this.change();
252 | }
253 | }
254 | },
255 | toMove (distance, duration) {
256 | const speed = Math.abs(distance / duration);
257 | distance = this.startTop + (speed / 0.002) * (distance < 0 ? -1 : 1);
258 | this.ulStyle.transitionProperty = `all`;
259 | this.ulStyle.transitionDuration = `1000ms`;
260 | this.setTop(Math.min(Math.max(Math.round(-distance / this.itemHeight), 0), this.count - 1));
261 | },
262 | change () {
263 | this.$emit('change', this.column[this.selectIndex]);
264 | },
265 | mousewheel (e) {
266 | e.preventDefault();
267 | e.stopPropagation();
268 | this.ulStyle.transitionDuration = `0ms`;
269 | this.ulStyle.transitionProperty = `none`;
270 | const { deltaX, deltaY } = e;
271 | if (Math.abs(deltaX) < Math.abs(deltaY)) {
272 | this.startTop = this.startTop - deltaY;
273 | let b = this.bottom - this.itemHeight;
274 | let t = this.top + this.itemHeight;
275 | let shouldMove = true;
276 | if (this.startTop > b ) {
277 | this.startTop = b;
278 | shouldMove = false;
279 | } else if (this.startTop < t) {
280 | this.startTop = t;
281 | shouldMove = false;
282 | }
283 | this.ulStyle.transform = `translate3d(0px, ${this.startTop}px, 0px)`;
284 | if (shouldMove) {
285 | clearInterval(this.wheelTimer);
286 | this.wheelTimer = setTimeout(this.setTranfromTop, 100);
287 | }
288 | }
289 | }
290 | },
291 | mounted () {
292 | this.init();
293 | // 监听开始事件
294 | this.$el.addEventListener(START_EVENT, this.handleStart, false);
295 | if (IS_PC) {
296 | this.$el.addEventListener('wheel', this.mousewheel, false);
297 | } else {
298 | this.$el.addEventListener(MOVE_EVENT, this.handleMove, false);
299 | this.$el.addEventListener(END_EVENT, this.handleEnd, false);
300 | }
301 | },
302 | watch: {
303 | column () {
304 | this.init();
305 | },
306 | defaultIndex () {
307 | this.setTop(this.defaultIndex);
308 | }
309 | },
310 | beforeDestroy () {
311 | this.$el.removeEventListener(START_EVENT, this.handleStart, false);
312 | if (IS_PC) {
313 | this.$el.removeEventListener('wheel', this.mousewheel, false);
314 | this.$el.removeEventListener(MOVE_EVENT, this.handleMove, false);
315 | this.$el.removeEventListener(END_EVENT, this.handleEnd, false);
316 | }
317 | }
318 | };
319 |
320 | /* script */
321 | const __vue_script__$1 = script$1;
322 |
323 | /* template */
324 | var __vue_render__$1 = function() {
325 | var _vm = this;
326 | var _h = _vm.$createElement;
327 | var _c = _vm._self._c || _h;
328 | return _c("div", { ref: "list", staticClass: "list" }, [
329 | _c(
330 | "ul",
331 | { style: _vm.ulStyle },
332 | _vm._l(_vm.column, function(item, index) {
333 | return _c("li", { key: "item" + index }, [_vm._v(_vm._s(item.label))])
334 | }),
335 | 0
336 | )
337 | ])
338 | };
339 | var __vue_staticRenderFns__$1 = [];
340 | __vue_render__$1._withStripped = true;
341 |
342 | /* style */
343 | const __vue_inject_styles__$1 = function (inject) {
344 | if (!inject) return
345 | inject("data-v-ec129ff4_0", { source: ".list[data-v-ec129ff4] {\n margin: 0;\n padding: 0;\n -webkit-box-flex: 1;\n flex: 1;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.list ul[data-v-ec129ff4] {\n margin: 0;\n padding: 0;\n -webkit-transition-timing-function: cubic-bezier(0.23, 1, 0.68, 1);\n transition-timing-function: cubic-bezier(0.23, 1, 0.68, 1);\n line-height: 44px;\n}\n.list li[data-v-ec129ff4] {\n margin: 0;\n padding: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n padding: 0 5px;\n color: #000;\n}\n\n/*# sourceMappingURL=list.vue.map */", map: {"version":3,"sources":["/Users/naice/my-project/vue-picker/src/list.vue","list.vue"],"names":[],"mappings":"AA4MA;EACA,SAAA;EACA,UAAA;EACA,mBAAA;UAAA,OAAA;EACA,WAAA;EACA,YAAA;EACA,gBAAA;AC3MA;AD4MA;EACA,SAAA;EACA,UAAA;EACA,kEAAA;UAAA,0DAAA;EACA,iBAAA;AC1MA;AD4MA;EACA,SAAA;EACA,UAAA;EACA,gBAAA;EACA,mBAAA;EACA,uBAAA;EACA,cAAA;EACA,WAAA;AC1MA;;AAEA,mCAAmC","file":"list.vue","sourcesContent":["\n \n \n\n\n\n\n",".list {\n margin: 0;\n padding: 0;\n flex: 1;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.list ul {\n margin: 0;\n padding: 0;\n transition-timing-function: cubic-bezier(0.23, 1, 0.68, 1);\n line-height: 44px;\n}\n.list li {\n margin: 0;\n padding: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n padding: 0 5px;\n color: #000;\n}\n\n/*# sourceMappingURL=list.vue.map */"]}, media: undefined });
346 |
347 | };
348 | /* scoped */
349 | const __vue_scope_id__$1 = "data-v-ec129ff4";
350 | /* module identifier */
351 | const __vue_module_identifier__$1 = undefined;
352 | /* functional template */
353 | const __vue_is_functional_template__$1 = false;
354 | /* style inject SSR */
355 |
356 | /* style inject shadow dom */
357 |
358 |
359 |
360 | var List = normalizeComponent(
361 | { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
362 | __vue_inject_styles__$1,
363 | __vue_script__$1,
364 | __vue_scope_id__$1,
365 | __vue_is_functional_template__$1,
366 | __vue_module_identifier__$1,
367 | false,
368 | createInjector,
369 | undefined,
370 | undefined
371 | );
372 |
373 | //
374 | var script$2 = {
375 | name: 'VuePicker',
376 | props: {
377 | visible: {
378 | type: Boolean,
379 | default: false
380 | },
381 | data: {
382 | type: Array,
383 | default: () => []
384 | },
385 | layer: {
386 | type: Number,
387 | default: 0
388 | },
389 | itemHeight: {
390 | type: [Number, String],
391 | default: DEFTAULT_ITEM_HEIGHT
392 | },
393 | defaultIndex: {
394 | type: [Number, Array],
395 | default: 0
396 | },
397 | cancelText: {
398 | type: String,
399 | default: '取消'
400 | },
401 | confirmText: {
402 | type: String,
403 | default: '确认'
404 | },
405 | title: {
406 | type: String,
407 | default: ''
408 | },
409 | showToolbar: {
410 | type: Boolean,
411 | default: false
412 | },
413 | maskClick: {
414 | type: Boolean,
415 | default: false
416 | },
417 | rowNumber: {
418 | type: Number,
419 | default: 5
420 | },
421 | appendToBody: {
422 | type: Boolean,
423 | default: false
424 | }
425 | },
426 | components: {
427 | Header,
428 | List
429 | },
430 | data () {
431 | return {
432 | column1: [],
433 | column2: [],
434 | column3: [],
435 | column4: [],
436 | dIndex1: 0,
437 | dIndex2: 0,
438 | dIndex3: 0,
439 | dIndex4: 0
440 | }
441 | },
442 | computed: {
443 | boxHeight () {
444 | let itemHeight = parseInt(this.itemHeight);
445 | itemHeight = itemHeight ? itemHeight : DEFTAULT_ITEM_HEIGHT;
446 | return itemHeight * this.getRowNumber
447 | },
448 | getRowNumber () {
449 | if (this.rowNumber < 3) {
450 | return 3
451 | }
452 | return this.rowNumber % 2 === 0 ? this.rowNumber + 1 : this.rowNumber
453 | },
454 | maskStyle() {
455 | let style = { backgroundSize: '100% 88px' };
456 | if (this.getRowNumber === 3) {
457 | style = { backgroundSize: '100% 44px' };
458 | }
459 | return style
460 | }
461 | },
462 | methods: {
463 | clickMask () {
464 | if (this.maskClick) {
465 | this.looseBody();
466 | this.$emit('update:visible', false);
467 | }
468 | },
469 | formateData () {
470 | if (this.layer > 1) {
471 | this.setLinkColumn();
472 | } else {
473 | this.column1 = this.data[0] || [];
474 | this.column2 = this.data[1] || [];
475 | this.column3 = this.data[2] || [];
476 | this.column4 = this.data[3] || [];
477 | this.setNormalIndex();
478 | }
479 | },
480 | setLinkColumn () {
481 | if (this.layer === 2) {
482 | this.setLinkLayer2();
483 | } else if (this.layer === 3) {
484 | this.setLinkLayer2();
485 | this.setLinkLayer3();
486 | } else if (this.layer === 4) {
487 | this.setLinkLayer2();
488 | this.setLinkLayer3();
489 | this.setLinkLayer4();
490 | }
491 | },
492 | setLinkLayer2 () {
493 | const { defaultIndex } = this;
494 | this.column1 = this.data || [];
495 | if (typeof defaultIndex === 'number') {
496 | this.dIndex1 = defaultIndex;
497 | this.dIndex2 = 0;
498 | if (this.data.length > 1 && this.data[0].children) {
499 | this.column2 = this.data[0].children || [];
500 | }
501 | } else if (Array.isArray(defaultIndex) && defaultIndex.length > 0){
502 | this.dIndex1 = defaultIndex[0] || 0;
503 | this.column2 = this.data[this.dIndex1].children || [];
504 | this.$nextTick(() => {
505 | if (this.column2.length - 1 < defaultIndex[1]) {
506 | this.dIndex2 = this.column2.length - 1;
507 | } else {
508 | this.dIndex2 = defaultIndex[1] || 0;
509 | }
510 | });
511 | }
512 | },
513 | setLinkLayer3 () {
514 | const { defaultIndex } = this;
515 | if (typeof defaultIndex === 'number') {
516 | this.dIndex3 = 0;
517 | if (this.column2.length > 1 && this.column2[0].children) {
518 | this.column3 = this.column2[0].children || [];
519 | }
520 | } else if (Array.isArray(defaultIndex) && defaultIndex.length > 1){
521 | this.$nextTick(() => {
522 | this.column3 = this.column2[this.dIndex2].children || [];
523 | this.$nextTick(() => {
524 | if (this.column3.length - 1 < defaultIndex[2]) {
525 | this.dIndex3 = this.column3.length - 1;
526 | } else {
527 | this.dIndex3 = defaultIndex[2] || 0;
528 | }
529 | });
530 | });
531 | }
532 | },
533 | setLinkLayer4 () {
534 | const { defaultIndex } = this;
535 | if (typeof defaultIndex === 'number') {
536 | this.dIndex4 = 0;
537 | if (this.column3.length > 1 && this.column3[0].children) {
538 | this.column4 = this.column3[0].children || [];
539 | }
540 | } else if (Array.isArray(defaultIndex) && defaultIndex.length > 2){
541 | setTimeout(() => {
542 | this.column4 = this.column3[this.dIndex3].children || [];
543 | this.$nextTick(() => {
544 | if (this.column4.length - 1 < defaultIndex[3]) {
545 | this.dIndex4 = this.column4.length - 1;
546 | } else {
547 | this.dIndex4 = defaultIndex[3] || 0;
548 | }
549 | });
550 | });
551 | }
552 | },
553 | setNormalIndex () {
554 | this.$nextTick(() => {
555 | const { defaultIndex } = this;
556 | if (Array.isArray(defaultIndex)) {
557 | this.setDefaultIndex();
558 | } else {
559 | this.dIndex1 = Number(defaultIndex) || 0;
560 | }
561 | });
562 | },
563 | setDefaultIndex () {
564 | const { indexArr } = this;
565 | const self = this;
566 | function next() {
567 | let promise = Promise.resolve();
568 | let index = 0;
569 | while (index < self.data.length) {
570 | promise = promise.then(indexArr[index]);
571 | index++;
572 | }
573 | }
574 | next();
575 | },
576 | change (index, res) {
577 | this.result[index] = res;
578 | this.$emit('change', this.result);
579 | },
580 | change1 (res) {
581 | if (res) {
582 | this.change(0, res);
583 | if (this.layer > 1) {
584 | this.dIndex2 = 0;
585 | this.changeLink('column2', res);
586 | }
587 | }
588 | },
589 | change2 (res) {
590 | if (res) {
591 | this.change(1, res);
592 | if (this.layer > 2) {
593 | this.dIndex3 = 0;
594 | this.changeLink('column3', res);
595 | }
596 | }
597 | },
598 | change3 (res) {
599 | if (res) {
600 | this.change(2, res);
601 | if (this.layer > 3) {
602 | this.dIndex4 = 0;
603 | this.changeLink('column4', res);
604 | }
605 | }
606 | },
607 | change4 (res) {
608 | if (res) {
609 | this.change(3, res);
610 | }
611 | },
612 | changeLink (key, res) {
613 | if (this.layer) {
614 | // clearTimeout(this.linktimer)
615 | this.linktimer = setTimeout(() => {
616 | this[key] = res.children || [];
617 | }, 1000 / 60);
618 | }
619 | },
620 | cancel () {
621 | this.looseBody();
622 | this.$emit('cancel');
623 | this.$emit('update:visible', false);
624 | },
625 | confirm () {
626 | this.looseBody();
627 | this.$emit('confirm', this.result);
628 | this.$emit('update:visible', false);
629 | },
630 | stopPropagation (e) {
631 | e.stopPropagation();
632 | },
633 | fixedBody() {
634 | const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
635 | this.prevBodyCss = document.body.style.cssText;
636 | document.body.style.cssText += 'position:fixed;width:100%;top:-' + scrollTop + 'px;';
637 | },
638 | looseBody() {
639 | const body = document.body;
640 | const top = body.style.top;
641 | body.style.cssText = this.prevBodyCss;
642 | body.scrollTop = document.documentElement.scrollTop = -parseInt(top);
643 | body.style.top = '';
644 | },
645 | init() {
646 | this.result = [];
647 | this.indexArr = [
648 | () => this.dIndex1 = this.defaultIndex[0] || 0,
649 | () => this.dIndex2 = this.defaultIndex[1] || 0,
650 | () => this.dIndex3 = this.defaultIndex[2] || 0,
651 | () => this.dIndex4 = this.defaultIndex[3] || 0
652 | ];
653 | this.formateData();
654 | }
655 | },
656 | created () {
657 | this.init();
658 | },
659 | mounted () {
660 | this.$refs.picker.addEventListener('click', this.stopPropagation);
661 | if (this.appendToBody) {
662 | document.body.appendChild(this.$el);
663 | }
664 | },
665 | watch: {
666 | visible (v) {
667 | if (v) {
668 | this.fixedBody();
669 | }
670 | },
671 | defaultIndex () {
672 | this.init();
673 | },
674 | data() {
675 | this.init();
676 | }
677 | },
678 | beforeDestroy () {
679 | this.$refs.picker.removeEventListener('click', this.stopPropagation);
680 | }
681 | };
682 |
683 | /* script */
684 | const __vue_script__$2 = script$2;
685 |
686 | /* template */
687 | var __vue_render__$2 = function() {
688 | var _vm = this;
689 | var _h = _vm.$createElement;
690 | var _c = _vm._self._c || _h;
691 | return _c("transition", { attrs: { name: "fade" } }, [
692 | _c(
693 | "div",
694 | {
695 | directives: [
696 | {
697 | name: "show",
698 | rawName: "v-show",
699 | value: _vm.visible,
700 | expression: "visible"
701 | }
702 | ],
703 | staticClass: "pickerbox",
704 | on: { click: _vm.clickMask }
705 | },
706 | [
707 | _c("transition", { attrs: { name: "toup" } }, [
708 | _c(
709 | "div",
710 | {
711 | directives: [
712 | {
713 | name: "show",
714 | rawName: "v-show",
715 | value: _vm.visible,
716 | expression: "visible"
717 | }
718 | ],
719 | ref: "picker",
720 | staticClass: "vue-picker"
721 | },
722 | [
723 | _vm.showToolbar
724 | ? _c("Header", {
725 | attrs: {
726 | cancelText: _vm.cancelText,
727 | confirmText: _vm.confirmText,
728 | title: _vm.title
729 | },
730 | on: { cancel: _vm.cancel, confirm: _vm.confirm }
731 | })
732 | : _vm._e(),
733 | _vm._v(" "),
734 | _c(
735 | "div",
736 | {
737 | staticClass: "content",
738 | style: { height: _vm.boxHeight + "px" }
739 | },
740 | [
741 | _c(
742 | "div",
743 | { staticClass: "colums" },
744 | [
745 | _c("List", {
746 | attrs: {
747 | column: _vm.column1,
748 | boxHeight: _vm.boxHeight,
749 | itemHeight: _vm.itemHeight,
750 | defaultIndex: _vm.dIndex1,
751 | rowNumber: _vm.getRowNumber
752 | },
753 | on: { change: _vm.change1 }
754 | }),
755 | _vm._v(" "),
756 | _vm.column2.length > 0
757 | ? _c("List", {
758 | attrs: {
759 | column: _vm.column2,
760 | boxHeight: _vm.boxHeight,
761 | itemHeight: _vm.itemHeight,
762 | defaultIndex: _vm.dIndex2,
763 | rowNumber: _vm.getRowNumber
764 | },
765 | on: { change: _vm.change2 }
766 | })
767 | : _vm._e(),
768 | _vm._v(" "),
769 | _vm.column3.length > 0
770 | ? _c("List", {
771 | attrs: {
772 | column: _vm.column3,
773 | boxHeight: _vm.boxHeight,
774 | itemHeight: _vm.itemHeight,
775 | defaultIndex: _vm.dIndex3,
776 | rowNumber: _vm.getRowNumber
777 | },
778 | on: { change: _vm.change3 }
779 | })
780 | : _vm._e(),
781 | _vm._v(" "),
782 | _vm.column4.length > 0
783 | ? _c("List", {
784 | attrs: {
785 | column: _vm.column4,
786 | boxHeight: _vm.boxHeight,
787 | itemHeight: _vm.itemHeight,
788 | defaultIndex: _vm.dIndex4,
789 | rowNumber: _vm.getRowNumber
790 | },
791 | on: { change: _vm.change4 }
792 | })
793 | : _vm._e()
794 | ],
795 | 1
796 | ),
797 | _vm._v(" "),
798 | _c("div", { staticClass: "mask", style: _vm.maskStyle }),
799 | _vm._v(" "),
800 | _c("div", { staticClass: "hairline" })
801 | ]
802 | )
803 | ],
804 | 1
805 | )
806 | ])
807 | ],
808 | 1
809 | )
810 | ])
811 | };
812 | var __vue_staticRenderFns__$2 = [];
813 | __vue_render__$2._withStripped = true;
814 |
815 | /* style */
816 | const __vue_inject_styles__$2 = function (inject) {
817 | if (!inject) return
818 | inject("data-v-176a7813_0", { source: ".pickerbox[data-v-176a7813] {\n position: fixed;\n width: 100vw;\n height: 100vh;\n left: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 9999;\n overflow: hidden;\n}\n.fade-enter-active[data-v-176a7813], .fade-leave-active[data-v-176a7813] {\n -webkit-transition: opacity 0.2s;\n transition: opacity 0.2s;\n}\n.fade-enter[data-v-176a7813], .fade-leave-to[data-v-176a7813] {\n opacity: 0;\n}\n.toup-enter-active[data-v-176a7813], .toup-leave-active[data-v-176a7813] {\n -webkit-transition: -webkit-transform 0.3s;\n transition: -webkit-transform 0.3s;\n transition: transform 0.3s;\n transition: transform 0.3s, -webkit-transform 0.3s;\n}\n.toup-enter[data-v-176a7813], .toup-leave-to[data-v-176a7813] {\n -webkit-transform: translate3d(0, 100px, 0);\n transform: translate3d(0, 100px, 0);\n}\n.vue-picker[data-v-176a7813] {\n position: absolute;\n left: 0;\n bottom: 0;\n width: 100%;\n background-color: #fff;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: transparent;\n display: block;\n}\n.content[data-v-176a7813] {\n overflow: hidden;\n height: 220px;\n position: relative;\n display: -webkit-box;\n display: flex;\n}\n.colums[data-v-176a7813] {\n display: -webkit-box;\n display: flex;\n overflow: hidden;\n font-size: 16px;\n text-align: center;\n -webkit-box-flex: 1;\n flex: 1;\n}\n.mask[data-v-176a7813] {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n width: 100%;\n height: 100%;\n background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.9)), to(rgba(255, 255, 255, 0.4))), -webkit-gradient(linear, left bottom, left top, from(rgba(255, 255, 255, 0.9)), to(rgba(255, 255, 255, 0.4)));\n background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)), linear-gradient(0deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4));\n background-repeat: no-repeat;\n background-position: top, bottom;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n pointer-events: none;\n background-size: 100% 88px;\n}\n.hairline[data-v-176a7813] {\n position: absolute;\n top: 50%;\n left: 0;\n z-index: 3;\n width: 100%;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n pointer-events: none;\n height: 44px;\n}\n.hairline[data-v-176a7813]::after {\n position: absolute;\n box-sizing: border-box;\n content: \" \";\n pointer-events: none;\n top: -50%;\n right: -50%;\n bottom: -50%;\n left: -50%;\n border: 0 solid #ebedf0;\n -webkit-transform: scale(0.5);\n transform: scale(0.5);\n border-width: 1px 0;\n}\n\n/*# sourceMappingURL=index.vue.map */", map: {"version":3,"sources":["/Users/naice/my-project/vue-picker/src/index.vue","index.vue"],"names":[],"mappings":"AA2WA;EACA,eAAA;EACA,YAAA;EACA,aAAA;EACA,OAAA;EACA,SAAA;EACA,8BAAA;EACA,aAAA;EACA,gBAAA;AC1WA;AD4WA;EACA,gCAAA;EAAA,wBAAA;ACzWA;AD2WA;EACA,UAAA;ACxWA;AD0WA;EACA,0CAAA;EAAA,kCAAA;EAAA,0BAAA;EAAA,kDAAA;ACvWA;ADyWA;EACA,2CAAA;UAAA,mCAAA;ACtWA;ADyWA;EACA,kBAAA;EACA,OAAA;EACA,SAAA;EACA,WAAA;EACA,sBAAA;EACA,yBAAA;KAAA,sBAAA;MAAA,qBAAA;UAAA,iBAAA;EACA,8BAAA;EACA,wCAAA;EACA,cAAA;ACtWA;ADwWA;EACA,gBAAA;EACA,aAAA;EACA,kBAAA;EACA,oBAAA;EAAA,aAAA;ACrWA;ADuWA;EACA,oBAAA;EAAA,aAAA;EACA,gBAAA;EACA,eAAA;EACA,kBAAA;EACA,mBAAA;UAAA,OAAA;ACpWA;ADsWA;EACA,kBAAA;EACA,MAAA;EACA,OAAA;EACA,UAAA;EACA,WAAA;EACA,YAAA;EACA,8OAAA;EAAA,wKAAA;EACA,4BAAA;EACA,gCAAA;EACA,mCAAA;UAAA,2BAAA;EACA,oBAAA;EACA,0BAAA;ACnWA;ADqWA;EACA,kBAAA;EACA,QAAA;EACA,OAAA;EACA,UAAA;EACA,WAAA;EACA,mCAAA;UAAA,2BAAA;EACA,oBAAA;EACA,YAAA;AClWA;ADmWA;EACA,kBAAA;EACA,sBAAA;EACA,YAAA;EACA,oBAAA;EACA,SAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,uBAAA;EACA,6BAAA;EACA,qBAAA;EACA,mBAAA;ACjWA;;AAEA,oCAAoC","file":"index.vue","sourcesContent":["\n \n \n
\n \n
\n
\n
\n
\n 0\"\n :column=\"column2\"\n :boxHeight=\"boxHeight\"\n :itemHeight=\"itemHeight\"\n :defaultIndex=\"dIndex2\"\n :rowNumber=\"getRowNumber\"\n @change=\"change2\" />\n 0\"\n :column=\"column3\"\n :boxHeight=\"boxHeight\"\n :itemHeight=\"itemHeight\"\n :defaultIndex=\"dIndex3\"\n :rowNumber=\"getRowNumber\"\n @change=\"change3\" />\n 0\"\n :column=\"column4\"\n :boxHeight=\"boxHeight\"\n :itemHeight=\"itemHeight\"\n :defaultIndex=\"dIndex4\"\n :rowNumber=\"getRowNumber\"\n @change=\"change4\" />\n
\n
\n
\n
\n
\n \n
\n \n \n\n\n",".pickerbox {\n position: fixed;\n width: 100vw;\n height: 100vh;\n left: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 9999;\n overflow: hidden;\n}\n\n.fade-enter-active, .fade-leave-active {\n transition: opacity 0.2s;\n}\n\n.fade-enter, .fade-leave-to {\n opacity: 0;\n}\n\n.toup-enter-active, .toup-leave-active {\n transition: transform 0.3s;\n}\n\n.toup-enter, .toup-leave-to {\n transform: translate3d(0, 100px, 0);\n}\n\n.vue-picker {\n position: absolute;\n left: 0;\n bottom: 0;\n width: 100%;\n background-color: #fff;\n user-select: none;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: transparent;\n display: block;\n}\n\n.content {\n overflow: hidden;\n height: 220px;\n position: relative;\n display: flex;\n}\n\n.colums {\n display: flex;\n overflow: hidden;\n font-size: 16px;\n text-align: center;\n flex: 1;\n}\n\n.mask {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n width: 100%;\n height: 100%;\n background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)), linear-gradient(0deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4));\n background-repeat: no-repeat;\n background-position: top, bottom;\n backface-visibility: hidden;\n pointer-events: none;\n background-size: 100% 88px;\n}\n\n.hairline {\n position: absolute;\n top: 50%;\n left: 0;\n z-index: 3;\n width: 100%;\n transform: translateY(-50%);\n pointer-events: none;\n height: 44px;\n}\n.hairline::after {\n position: absolute;\n box-sizing: border-box;\n content: \" \";\n pointer-events: none;\n top: -50%;\n right: -50%;\n bottom: -50%;\n left: -50%;\n border: 0 solid #ebedf0;\n -webkit-transform: scale(0.5);\n transform: scale(0.5);\n border-width: 1px 0;\n}\n\n/*# sourceMappingURL=index.vue.map */"]}, media: undefined });
819 |
820 | };
821 | /* scoped */
822 | const __vue_scope_id__$2 = "data-v-176a7813";
823 | /* module identifier */
824 | const __vue_module_identifier__$2 = undefined;
825 | /* functional template */
826 | const __vue_is_functional_template__$2 = false;
827 | /* style inject SSR */
828 |
829 | /* style inject shadow dom */
830 |
831 |
832 |
833 | var index = normalizeComponent(
834 | { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 },
835 | __vue_inject_styles__$2,
836 | __vue_script__$2,
837 | __vue_scope_id__$2,
838 | __vue_is_functional_template__$2,
839 | __vue_module_identifier__$2,
840 | false,
841 | createInjector,
842 | undefined,
843 | undefined
844 | );
845 |
846 | export default index;
847 |
--------------------------------------------------------------------------------
/example/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naihe138/vue-picker/2aed086132dc327206cd19a9f67d1de8f1532500/example/.DS_Store
--------------------------------------------------------------------------------
/example/css/app.279fbbfe.css:
--------------------------------------------------------------------------------
1 | .header[data-v-70603ee2]{height:120px;background:#2fc6ff;color:#fff;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:30px;font-weight:500}.header[data-v-70603ee2],.nav[data-v-70603ee2]{display:-webkit-box;display:-ms-flexbox;display:flex}.nav[data-v-70603ee2]{-ms-flex-pack:distribute;justify-content:space-around;overflow:hidden;padding:10px;-ms-flex-wrap:wrap;flex-wrap:wrap}.nav span[data-v-70603ee2]{display:inline-block;text-decoration:none;border:1px solid #2fc6ff;padding:5px 10px;font-size:14px;margin-bottom:10px}.nav .active[data-v-70603ee2]{background:#2fc6ff;color:#fff}.tips[data-v-70603ee2]{background:rgba(0,0,0,.5);position:fixed;width:100px;height:26px;line-height:26px;text-align:center;font-size:14px;border-radius:4px;color:#fff;left:50%;top:50%;margin:-13px 0 0 -50px}.slide-fade-enter-active[data-v-70603ee2]{-webkit-transition:all .3s ease;transition:all .3s ease}.slide-fade-leave-active[data-v-70603ee2]{-webkit-transition:all .3s cubic-bezier(1,.5,.8,1);transition:all .3s cubic-bezier(1,.5,.8,1)}.slide-fade-enter[data-v-70603ee2],.slide-fade-leave-to[data-v-70603ee2]{-webkit-transform:translateY(-30px);transform:translateY(-30px);opacity:0}.btnbox{margin-top:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btnbox .btn{background:#2e68fa;color:#fff;padding:5px 10px;display:inline-block;margin:0 10px;font-size:14px;border-radius:4px}.result{font-size:14px;text-align:center}.result p:nth-of-type(2){padding:0 10px;color:#004af5;line-height:2}body{margin:0;padding:0;background-color:#f8f8f8;font-family:PingFang SC,Helvetica,STHeiti STXihei,Microsoft YaHei,Tohoma,Arial,sans-serif;line-height:1;-webkit-font-smoothing:antialiased}
--------------------------------------------------------------------------------
/example/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/naihe138/vue-picker/2aed086132dc327206cd19a9f67d1de8f1532500/example/favicon.ico
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
vue-picker-mayun We're sorry but vue-picker-mayun doesn't work properly without JavaScript enabled. Please enable it to continue.
--------------------------------------------------------------------------------
/example/js/app.5d01ef29.js:
--------------------------------------------------------------------------------
1 | (function(n){function l(l){for(var a,c,u=l[0],s=l[1],r=l[2],v=0,o=[];v\n \n \n
\n\n\n
38 |
39 |
76 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | import Picker from './index.vue'
3 |
4 | if (typeof window !== 'undefined' && window.Vue) {
5 | window.Vue.component('vue-picker', Picker)
6 | }
7 |
8 | Picker.install = function(Vue){
9 | Vue.component(Picker.name, Picker)
10 | }
11 |
12 | export default Picker
13 |
--------------------------------------------------------------------------------
/src/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
14 |
20 |
27 |
34 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
363 |
450 |
--------------------------------------------------------------------------------
/src/list.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
203 |
204 |
229 |
--------------------------------------------------------------------------------
/src/picker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
16 |
22 |
28 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
227 |
228 |
288 |
--------------------------------------------------------------------------------
/src/render.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | import Vue from 'vue'
3 |
4 | const textRender = Vue.component('text-render', {
5 | functional: true,
6 | props: {
7 | crender: {
8 | type: Function,
9 | default: function () {}
10 | },
11 | value: {
12 | type: [Object, Number, String, Boolean, Array],
13 | default: function () {
14 | return {}
15 | }
16 | },
17 | column: {
18 | type: Object,
19 | default: function () {
20 | return {}
21 | }
22 | },
23 | index: {
24 | type: [Number, String],
25 | default: 0
26 | },
27 | row: {
28 | type: Object,
29 | default: function () {
30 | return {}
31 | }
32 | }
33 | },
34 | render (h, self) {
35 | return self.props.crender(h, { index: self.props.index, value: self.props.value, column: self.props.column, row: self.props.row })
36 | }
37 | })
38 |
39 | export default textRender
40 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | export const DEFTAULT_ITEM_HEIGHT = 44
3 |
4 | // 兼容pc 移动端
5 | export const HAS_TOUCH = 'ontouchstart' in window
6 | export const START_EVENT = HAS_TOUCH ? 'touchstart' : 'mousedown'
7 | export const MOVE_EVENT = HAS_TOUCH ? 'touchmove' : 'mousemove'
8 | export const END_EVENT = HAS_TOUCH ? 'touchend' : 'mouseup'
9 |
10 | export const getClient = e => {
11 | let clientX = HAS_TOUCH ? e.changedTouches[0].clientX : e.clientX
12 | let clientY = HAS_TOUCH ? e.changedTouches[0].clientY : e.clientY
13 | return {
14 | x: clientX,
15 | y: clientY
16 | }
17 | }
18 | export const isPC = () => {
19 | const userAgentInfo = navigator.userAgent
20 | const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
21 | let flag = true
22 | for (var v = 0; v < Agents.length; v++) {
23 | if (userAgentInfo.indexOf(Agents[v]) > 0) {
24 | flag = false
25 | break
26 | }
27 | }
28 | return flag
29 | }
30 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const TerserJSPlugin = require('terser-webpack-plugin')
4 |
5 | module.exports = {
6 | mode: 'production',
7 | entry: './dist/index.js',
8 | output: {
9 | path: path.resolve(__dirname, './lib'),
10 | publicPath: '/lib/',
11 | filename: 'vue-picker.js',
12 | library: 'vue-picker',
13 | libraryTarget: 'umd',
14 | umdNamedDefine: true
15 | },
16 | devtool: 'none',
17 | module: {
18 | rules: [
19 | {
20 | test: /\.js$/,
21 | use: {
22 | loader: 'babel-loader',
23 | options: {
24 | presets: ['@babel/preset-env']
25 | }
26 | },
27 | exclude: /node_modules/
28 | },
29 | ]
30 | },
31 | optimization: {
32 | minimizer: [
33 | new TerserJSPlugin({
34 | parallel: true,
35 | sourceMap: false,
36 | terserOptions: {
37 | compress: {
38 | inline: 1, // https://github.com/mishoo/UglifyJS2/issues/2842
39 | warnings: false,
40 | drop_console: true,
41 | drop_debugger: true
42 | },
43 | output: {
44 | comments: false
45 | }
46 | }
47 | })
48 | ]
49 | }
50 | }
51 |
--------------------------------------------------------------------------------