From 9bd5bb29dad5b5a920190cda3c4d8f9df3df0541 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Mon, 11 Dec 2017 14:57:31 +0800 Subject: [PATCH 01/19] init linkage component and example --- example/App.vue | 4 ++ example/main.js | 5 ++ example/pages/linkage-picker.vue | 41 ++++++++++++ .../linkage-picker/linkage-picker.vue | 67 +++++++++++++++++++ src/index.js | 2 + src/module.js | 2 + src/modules/linkage-picker/api.js | 11 +++ src/modules/linkage-picker/index.js | 15 +++++ 8 files changed, 147 insertions(+) create mode 100644 example/pages/linkage-picker.vue create mode 100644 src/components/linkage-picker/linkage-picker.vue create mode 100644 src/modules/linkage-picker/api.js create mode 100644 src/modules/linkage-picker/index.js diff --git a/example/App.vue b/example/App.vue index 26788ed15..304830f55 100644 --- a/example/App.vue +++ b/example/App.vue @@ -56,6 +56,10 @@ path: '/picker', text: 'Picker' }, + { + path: '/linkage-picker', + text: 'Linkage Picker' + }, { path: '/time-picker', text: 'TimePicker' diff --git a/example/main.js b/example/main.js index dd323393d..6e0e765a2 100644 --- a/example/main.js +++ b/example/main.js @@ -13,6 +13,7 @@ import Tip from './pages/tip.vue' import Popup from './pages/popup.vue' import Toast from './pages/toast.vue' import Picker from './pages/picker.vue' +import LinkagePicker from './pages/linkage-picker.vue' import TimePicker from './pages/time-picker.vue' import Dialog from './pages/dialog.vue' import ActionSheet from './pages/action-sheet.vue' @@ -56,6 +57,10 @@ const routes = [ path: '/picker', component: Picker }, + { + path: '/linkage-picker', + component: LinkagePicker + }, { path: '/time-picker', component: TimePicker diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue new file mode 100644 index 000000000..b67cf9855 --- /dev/null +++ b/example/pages/linkage-picker.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/components/linkage-picker/linkage-picker.vue b/src/components/linkage-picker/linkage-picker.vue new file mode 100644 index 000000000..18f2579e7 --- /dev/null +++ b/src/components/linkage-picker/linkage-picker.vue @@ -0,0 +1,67 @@ + + + diff --git a/src/index.js b/src/index.js index c2c556666..a46e6d385 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ import { Scroll, Popup, TimePicker, + LinkagePicker, Dialog, Tip, Toast, @@ -23,6 +24,7 @@ function install(Vue) { Style, Button, TimePicker, + LinkagePicker, Dialog, Tip, Toast, diff --git a/src/module.js b/src/module.js index 507158380..65e2aad4b 100644 --- a/src/module.js +++ b/src/module.js @@ -11,6 +11,7 @@ import ActionSheet from './modules/action-sheet' import Slide from './modules/slide' import IndexList from './modules/index-list' import TimePicker from './modules/time-picker' +import LinkagePicker from './modules/linkage-picker' import Scroll from './modules/scroll' import BScroll from './modules/better-scroll' @@ -28,6 +29,7 @@ export { Popup, Picker, TimePicker, + LinkagePicker, Dialog, Tip, Toast, diff --git a/src/modules/linkage-picker/api.js b/src/modules/linkage-picker/api.js new file mode 100644 index 000000000..692846367 --- /dev/null +++ b/src/modules/linkage-picker/api.js @@ -0,0 +1,11 @@ +import createAPI from '../../common/helpers/create-api' +import { warn } from '../../common/helpers/debug' + +export default function addLinkagePicker (Vue, LinkagePicker) { + const linkagePickerAPI = createAPI(Vue, LinkagePicker, ['select', 'cancel', 'change']) + linkagePickerAPI.before((data, renderFn, single) => { + if (single) { + warn('LinkagePicker component can not be a singleton.') + } + }) +} diff --git a/src/modules/linkage-picker/index.js b/src/modules/linkage-picker/index.js new file mode 100644 index 000000000..6ffbe1e2f --- /dev/null +++ b/src/modules/linkage-picker/index.js @@ -0,0 +1,15 @@ +import Picker from '../../components/picker/picker.vue' +import LinkagePicker from '../../components/linkage-picker/linkage-picker.vue' +import addLinkagePicker from './api' +import addPicker from '../picker/api' + +LinkagePicker.install = function (Vue) { + Vue.component(Picker.name, Picker) + Vue.component(LinkagePicker.name, LinkagePicker) + addPicker(Vue, Picker) + addLinkagePicker(Vue, LinkagePicker) +} + +LinkagePicker.Picker = Picker + +export default LinkagePicker From 906e0e415a2dd22d37ab6eea9176a3169408818d Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Mon, 11 Dec 2017 19:35:32 +0800 Subject: [PATCH 02/19] add linkage-picker: data handle --- example/pages/linkage-picker.vue | 59 ++++++++++++++++++- .../linkage-picker/linkage-picker.vue | 54 ++++++++++++++++- 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue index b67cf9855..6f03a34e9 100644 --- a/example/pages/linkage-picker.vue +++ b/example/pages/linkage-picker.vue @@ -12,11 +12,68 @@ import CubePage from 'example/components/cube-page.vue' import CubeButtonGroup from 'example/components/cube-button-group.vue' + const linkageData = [ + { + value: '北京', + text: '北京', + children: [ + { + value: '北京市', + text: '北京市', + children: [ + { + value: '海淀区', + text: '海淀区' + }, + { + value: '海淀区', + text: '海淀区' + } + ] + } + ] + }, + { + value: '江苏省', + text: '江苏省', + children: [ + { + value: '南京市', + text: '南京市', + children: [ + { + value: '1区', + text: '1区' + }, + { + value: '2区', + text: '2区' + } + ] + }, + { + value: '苏州市', + text: '苏州市', + children: [ + { + value: '3区', + text: '3区' + }, + { + value: '4区', + text: '4区' + } + ] + } + ] + } + ] + export default { mounted() { this.linkagePicker = this.$createLinkagePicker({ title: 'Linkage Picker', - data: this.linkageData, + data: linkageData, onChange: () => { console.log('change') }, diff --git a/src/components/linkage-picker/linkage-picker.vue b/src/components/linkage-picker/linkage-picker.vue index 18f2579e7..5c6a4f448 100644 --- a/src/components/linkage-picker/linkage-picker.vue +++ b/src/components/linkage-picker/linkage-picker.vue @@ -2,7 +2,7 @@ { + columnData.push({ + value: item.value, + text: item.text + }) + }) + pickerData.push(columnData) + + /* remain value */ +// const findIndex = columnData.findIndex((item) => { +// }) +// const nextI = findIndex !== -1 ? findIndex : 0 + data = data[this.tempIndex[i]].children + } + + return pickerData + } + }, + created() { + for (let i = 0; i < this.depth; i++) { + this.tempIndex.push(0) } }, methods: { @@ -56,8 +100,12 @@ _pickerCancel() { this.$emit(EVENT_CANCEL) }, - _pickerChange(index, selectedIndex) { - this.$emit(EVENT_CHANGE, index, selectedIndex) + _pickerChange(i, newIndex) { + if (newIndex !== this.tempIndex[i]) { + this.tempIndex.splice(i, 1, newIndex) + this.$refs.picker.refresh() + } + this.$emit(EVENT_CHANGE, i, newIndex) } }, components: { From 53206ec0bf2fd2fa1f2f37935dc9f509d2aff848 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Tue, 12 Dec 2017 13:41:34 +0800 Subject: [PATCH 03/19] add linkage and remain same value --- example/pages/linkage-picker.vue | 8 +-- .../linkage-picker/linkage-picker.vue | 66 +++++++++++-------- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue index 6f03a34e9..5f728bc83 100644 --- a/example/pages/linkage-picker.vue +++ b/example/pages/linkage-picker.vue @@ -56,12 +56,12 @@ text: '苏州市', children: [ { - value: '3区', - text: '3区' + value: '2区', + text: '2区' }, { - value: '4区', - text: '4区' + value: '3区', + text: '3区' } ] } diff --git a/src/components/linkage-picker/linkage-picker.vue b/src/components/linkage-picker/linkage-picker.vue index 5c6a4f448..669b3e48d 100644 --- a/src/components/linkage-picker/linkage-picker.vue +++ b/src/components/linkage-picker/linkage-picker.vue @@ -24,7 +24,7 @@ props: { title: { type: String, - default: '选择时间' + default: 'Linkage Picker' }, data: { type: Array, @@ -41,7 +41,8 @@ }, data () { return { - tempIndex: [] + tempIndex: [], + changeI: 0 } }, computed: { @@ -56,36 +57,13 @@ } } return depth - }, - pickerData() { - const pickerData = [] - let data = this.data - console.log(this.data) - console.log(data) - for (let i = 0; i < this.depth; i++) { - let columnData = [] - data.forEach((item) => { - columnData.push({ - value: item.value, - text: item.text - }) - }) - pickerData.push(columnData) - - /* remain value */ -// const findIndex = columnData.findIndex((item) => { -// }) -// const nextI = findIndex !== -1 ? findIndex : 0 - data = data[this.tempIndex[i]].children - } - - return pickerData } }, created() { for (let i = 0; i < this.depth; i++) { this.tempIndex.push(0) } + this.updatePickerData(true) }, methods: { show() { @@ -102,10 +80,44 @@ }, _pickerChange(i, newIndex) { if (newIndex !== this.tempIndex[i]) { + this.changeI = i this.tempIndex.splice(i, 1, newIndex) - this.$refs.picker.refresh() + this.updatePickerData() } this.$emit(EVENT_CHANGE, i, newIndex) + }, + updatePickerData(init) { + const pickerData = [] + let data = this.data + for (let i = 0; i < this.depth; i++) { + let columnData = [] + data.forEach((item) => { + columnData.push({ + value: item.value, + text: item.text + }) + }) + pickerData.push(columnData) + + if (!init && i > this.changeI) { + /* try to remain same value */ + const findIndex = columnData.findIndex((item) => { + return item.value === this.pickerData[i][this.tempIndex[i]].value + }) + this.tempIndex[i] = findIndex !== -1 ? findIndex : 0 + } + + data = data[this.tempIndex[i]].children + } + + this.pickerData = pickerData + if (!init) { + this.$refs.picker.setData(this.pickerData, this.tempIndex) + this.$refs.picker.refresh() + for (let j = this.changeI + 1; j < this.depth; j++) { + this.$refs.picker.scrollTo(j, this.tempIndex[j]) + } + } } }, components: { From 33401d403ce3d2387e8678c0783c03bc1d6122fc Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Tue, 12 Dec 2017 13:47:22 +0800 Subject: [PATCH 04/19] LinkagePicker: add propx selectedIndex --- example/pages/linkage-picker.vue | 1 + src/components/linkage-picker/linkage-picker.vue | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue index 5f728bc83..64423b81b 100644 --- a/example/pages/linkage-picker.vue +++ b/example/pages/linkage-picker.vue @@ -74,6 +74,7 @@ this.linkagePicker = this.$createLinkagePicker({ title: 'Linkage Picker', data: linkageData, + selectedIndex: [1, 1, 0], onChange: () => { console.log('change') }, diff --git a/src/components/linkage-picker/linkage-picker.vue b/src/components/linkage-picker/linkage-picker.vue index 669b3e48d..e418755f3 100644 --- a/src/components/linkage-picker/linkage-picker.vue +++ b/src/components/linkage-picker/linkage-picker.vue @@ -61,7 +61,7 @@ }, created() { for (let i = 0; i < this.depth; i++) { - this.tempIndex.push(0) + this.tempIndex.push(this.selectedIndex[i] || 0) } this.updatePickerData(true) }, From f689c601f12f838edfbe1c044a9201f4f6c06ff6 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Tue, 12 Dec 2017 15:49:32 +0800 Subject: [PATCH 05/19] LinkagePicker: update base demo --- example/App.vue | 2 +- example/pages/linkage-picker.vue | 200 ++++++++++++++++-- .../linkage-picker/linkage-picker.vue | 7 +- 3 files changed, 182 insertions(+), 27 deletions(-) diff --git a/example/App.vue b/example/App.vue index 304830f55..85bfe7a01 100644 --- a/example/App.vue +++ b/example/App.vue @@ -58,7 +58,7 @@ }, { path: '/linkage-picker', - text: 'Linkage Picker' + text: 'LinkagePicker' }, { path: '/time-picker', diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue index 64423b81b..8b3f7d641 100644 --- a/example/pages/linkage-picker.vue +++ b/example/pages/linkage-picker.vue @@ -14,54 +14,208 @@ const linkageData = [ { - value: '北京', - text: '北京', + value: 'Fruit', + text: 'Fruit', children: [ { - value: '北京市', - text: '北京市', + value: 'Apple', + text: 'Apple', children: [ { - value: '海淀区', - text: '海淀区' + value: 1, + text: 'One' }, { - value: '海淀区', - text: '海淀区' + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' + } + ] + }, + { + value: 'Orange', + text: 'Orange', + children: [ + { + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' + }, + { + value: 4, + text: 'Four' + } + ] + }, + { + value: 'Lemon', + text: 'Lemon', + children: [ + { + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' + }, + { + value: 4, + text: 'Four' + }, + { + value: 5, + text: 'Five' + } + ] + } + ] + }, + { + value: 'Drink', + text: 'Drink', + children: [ + { + value: 'Coffee', + text: 'Coffee', + children: [ + { + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' + } + ] + }, + { + value: 'Tee', + text: 'Tee', + children: [ + { + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' + }, + { + value: 4, + text: 'Four' + } + ] + }, + { + value: 'Juice', + text: 'Juice', + children: [ + { + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' } ] } ] }, { - value: '江苏省', - text: '江苏省', + value: 'Dessert', + text: 'Dessert', children: [ { - value: '南京市', - text: '南京市', + value: 'Chocolate', + text: 'Chocolate', children: [ { - value: '1区', - text: '1区' + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' }, { - value: '2区', - text: '2区' + value: 3, + text: 'Three' + }, + { + value: 4, + text: 'Four' + }, + { + value: 5, + text: 'Five' } ] }, { - value: '苏州市', - text: '苏州市', + value: 'cheese', + text: 'cheese', children: [ { - value: '2区', - text: '2区' + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' + }, + { + value: 3, + text: 'Three' + }, + { + value: 4, + text: 'Four' + } + ] + }, + { + value: 'cake', + text: 'cake', + children: [ + { + value: 1, + text: 'One' + }, + { + value: 2, + text: 'Two' }, { - value: '3区', - text: '3区' + value: 3, + text: 'Three' } ] } @@ -74,7 +228,7 @@ this.linkagePicker = this.$createLinkagePicker({ title: 'Linkage Picker', data: linkageData, - selectedIndex: [1, 1, 0], + selectedIndex: [1, 0, 0], onChange: () => { console.log('change') }, diff --git a/src/components/linkage-picker/linkage-picker.vue b/src/components/linkage-picker/linkage-picker.vue index e418755f3..fc24bb5e5 100644 --- a/src/components/linkage-picker/linkage-picker.vue +++ b/src/components/linkage-picker/linkage-picker.vue @@ -60,9 +60,6 @@ } }, created() { - for (let i = 0; i < this.depth; i++) { - this.tempIndex.push(this.selectedIndex[i] || 0) - } this.updatePickerData(true) }, methods: { @@ -99,6 +96,10 @@ }) pickerData.push(columnData) + if (init) { + this.tempIndex[i] = this.selectedIndex[i] || 0 + } + if (!init && i > this.changeI) { /* try to remain same value */ const findIndex = columnData.findIndex((item) => { From 63ea0874da515c392507c05d3fcdf44a49ac714a Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Tue, 12 Dec 2017 16:05:08 +0800 Subject: [PATCH 06/19] LinkagePicker: update city picker --- example/pages/linkage-picker.vue | 45 +++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue index 8b3f7d641..70097313f 100644 --- a/example/pages/linkage-picker.vue +++ b/example/pages/linkage-picker.vue @@ -3,6 +3,7 @@
Linkage Picker + City Picker
@@ -11,6 +12,7 @@ diff --git a/example/pages/linkage-picker.vue b/example/pages/linkage-picker.vue deleted file mode 100644 index 1b213b48d..000000000 --- a/example/pages/linkage-picker.vue +++ /dev/null @@ -1,312 +0,0 @@ - - - diff --git a/src/components/linkage-picker/linkage-picker.vue b/src/components/cascade-picker/cascade-picker.vue similarity index 94% rename from src/components/linkage-picker/linkage-picker.vue rename to src/components/cascade-picker/cascade-picker.vue index f5c09fa0a..3aaecc384 100644 --- a/src/components/linkage-picker/linkage-picker.vue +++ b/src/components/cascade-picker/cascade-picker.vue @@ -13,7 +13,7 @@ import CubePicker from '../picker/picker.vue' import apiMixin from '../../common/mixins/api' - const COMPONENT_NAME = 'cube-linkage-picker' + const COMPONENT_NAME = 'cube-cascade-picker' const EVENT_SELECT = 'select' const EVENT_CANCEL = 'cancel' const EVENT_CHANGE = 'change' @@ -24,7 +24,7 @@ props: { title: { type: String, - default: 'Linkage Picker' + default: 'Cascade Picker' }, data: { type: Array, @@ -41,7 +41,7 @@ }, data () { return { - linkageData: this.data.slice(), + cascadeData: this.data.slice(), pickerSelectedIndex: this.selectedIndex.slice(), pickerData: [] } @@ -59,7 +59,7 @@ this.$refs.picker.hide() }, setData(data, selectedIndex) { - this.linkageData = data + this.cascadeData = data this.pickerSelectedIndex = selectedIndex this.updatePickerData(true) }, @@ -79,7 +79,7 @@ }, updatePickerData(init) { const pickerData = [] - let data = this.linkageData + let data = this.cascadeData let i = 0 while (Array.isArray(data) && data.length) { let columnData = [] diff --git a/src/index.js b/src/index.js index a46e6d385..0e354fada 100644 --- a/src/index.js +++ b/src/index.js @@ -4,7 +4,7 @@ import { Scroll, Popup, TimePicker, - LinkagePicker, + CascadePicker, Dialog, Tip, Toast, @@ -24,7 +24,7 @@ function install(Vue) { Style, Button, TimePicker, - LinkagePicker, + CascadePicker, Dialog, Tip, Toast, diff --git a/src/module.js b/src/module.js index 65e2aad4b..6df0ae4c5 100644 --- a/src/module.js +++ b/src/module.js @@ -11,7 +11,7 @@ import ActionSheet from './modules/action-sheet' import Slide from './modules/slide' import IndexList from './modules/index-list' import TimePicker from './modules/time-picker' -import LinkagePicker from './modules/linkage-picker' +import CascadePicker from './modules/cascade-picker' import Scroll from './modules/scroll' import BScroll from './modules/better-scroll' @@ -29,7 +29,7 @@ export { Popup, Picker, TimePicker, - LinkagePicker, + CascadePicker, Dialog, Tip, Toast, diff --git a/src/modules/cascade-picker/api.js b/src/modules/cascade-picker/api.js new file mode 100644 index 000000000..6b1f83e07 --- /dev/null +++ b/src/modules/cascade-picker/api.js @@ -0,0 +1,11 @@ +import createAPI from '../../common/helpers/create-api' +import { warn } from '../../common/helpers/debug' + +export default function addCascadePicker (Vue, CascadePicker) { + const cascadePickerAPI = createAPI(Vue, CascadePicker, ['select', 'cancel', 'change']) + cascadePickerAPI.before((data, renderFn, single) => { + if (single) { + warn('CascadePicker component can not be a singleton.') + } + }) +} diff --git a/src/modules/cascade-picker/index.js b/src/modules/cascade-picker/index.js new file mode 100644 index 000000000..73c401102 --- /dev/null +++ b/src/modules/cascade-picker/index.js @@ -0,0 +1,15 @@ +import Picker from '../../components/picker/picker.vue' +import CascadePicker from '../../components/cascade-picker/cascade-picker.vue' +import addCascadePicker from './api' +import addPicker from '../picker/api' + +CascadePicker.install = function (Vue) { + Vue.component(Picker.name, Picker) + Vue.component(CascadePicker.name, CascadePicker) + addPicker(Vue, Picker) + addCascadePicker(Vue, CascadePicker) +} + +CascadePicker.Picker = Picker + +export default CascadePicker diff --git a/src/modules/linkage-picker/api.js b/src/modules/linkage-picker/api.js deleted file mode 100644 index 692846367..000000000 --- a/src/modules/linkage-picker/api.js +++ /dev/null @@ -1,11 +0,0 @@ -import createAPI from '../../common/helpers/create-api' -import { warn } from '../../common/helpers/debug' - -export default function addLinkagePicker (Vue, LinkagePicker) { - const linkagePickerAPI = createAPI(Vue, LinkagePicker, ['select', 'cancel', 'change']) - linkagePickerAPI.before((data, renderFn, single) => { - if (single) { - warn('LinkagePicker component can not be a singleton.') - } - }) -} diff --git a/src/modules/linkage-picker/index.js b/src/modules/linkage-picker/index.js deleted file mode 100644 index 6ffbe1e2f..000000000 --- a/src/modules/linkage-picker/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import Picker from '../../components/picker/picker.vue' -import LinkagePicker from '../../components/linkage-picker/linkage-picker.vue' -import addLinkagePicker from './api' -import addPicker from '../picker/api' - -LinkagePicker.install = function (Vue) { - Vue.component(Picker.name, Picker) - Vue.component(LinkagePicker.name, LinkagePicker) - addPicker(Vue, Picker) - addLinkagePicker(Vue, LinkagePicker) -} - -LinkagePicker.Picker = Picker - -export default LinkagePicker From 77b7709174b6242a2fb4098be8b07dcb7b57fa80 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 12:09:36 +0800 Subject: [PATCH 12/19] remove tempIndex --- .../cascade-picker/cascade-picker.vue | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/components/cascade-picker/cascade-picker.vue b/src/components/cascade-picker/cascade-picker.vue index 3aaecc384..b2c3d5e23 100644 --- a/src/components/cascade-picker/cascade-picker.vue +++ b/src/components/cascade-picker/cascade-picker.vue @@ -47,8 +47,7 @@ } }, created() { - this.tempIndex = [] - this.changeI = 0 + this.changedColumnIndex = 0 this.updatePickerData(true) }, methods: { @@ -70,9 +69,9 @@ this.$emit(EVENT_CANCEL) }, _pickerChange(i, newIndex) { - if (newIndex !== this.tempIndex[i]) { - this.changeI = i - this.tempIndex.splice(i, 1, newIndex) + if (newIndex !== this.pickerSelectedIndex[i]) { + this.changedColumnIndex = i + this.pickerSelectedIndex.splice(i, 1, newIndex) this.updatePickerData() } this.$emit(EVENT_CHANGE, i, newIndex) @@ -92,27 +91,27 @@ pickerData.push(columnData) if (init) { - this.tempIndex[i] = this.pickerSelectedIndex[i] || 0 + this.pickerSelectedIndex[i] = this.pickerSelectedIndex[i] || 0 } - if (!init && i > this.changeI) { + if (!init && i > this.changedColumnIndex) { /* try to remain same value */ const findIndex = columnData.findIndex((item) => { - return item.value === this.pickerData[i][this.tempIndex[i]].value + return item.value === this.pickerData[i][this.pickerSelectedIndex[i]].value }) - this.tempIndex[i] = findIndex !== -1 ? findIndex : 0 + this.pickerSelectedIndex[i] = findIndex !== -1 ? findIndex : 0 } - data = data[this.tempIndex[i]].children + data = data[this.pickerSelectedIndex[i]].children i++ } this.pickerData = pickerData if (!init) { - this.$refs.picker.setData(this.pickerData, this.tempIndex) + this.$refs.picker.setData(this.pickerData, this.pickerSelectedIndex) this.$refs.picker.refresh() - for (let j = this.changeI + 1; j < this.tempIndex.length; j++) { - this.$refs.picker.scrollTo(j, this.tempIndex[j]) + for (let j = this.changedColumnIndex + 1; j < this.pickerSelectedIndex.length; j++) { + this.$refs.picker.scrollTo(j, this.pickerSelectedIndex[j]) } } } From 8cb210584bd79e151ab9cb958a5858b77083f4c4 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 12:21:56 +0800 Subject: [PATCH 13/19] use refillColumn --- .../cascade-picker/cascade-picker.vue | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/components/cascade-picker/cascade-picker.vue b/src/components/cascade-picker/cascade-picker.vue index b2c3d5e23..2b29156b5 100644 --- a/src/components/cascade-picker/cascade-picker.vue +++ b/src/components/cascade-picker/cascade-picker.vue @@ -88,32 +88,14 @@ text: item.text }) }) - pickerData.push(columnData) - - if (init) { - this.pickerSelectedIndex[i] = this.pickerSelectedIndex[i] || 0 - } - - if (!init && i > this.changedColumnIndex) { - /* try to remain same value */ - const findIndex = columnData.findIndex((item) => { - return item.value === this.pickerData[i][this.pickerSelectedIndex[i]].value - }) - this.pickerSelectedIndex[i] = findIndex !== -1 ? findIndex : 0 - } - + pickerData[i] = columnData + this.pickerSelectedIndex[i] = init ? this.pickerSelectedIndex[i] || 0 : this.$refs.picker.refillColumn(i, columnData) data = data[this.pickerSelectedIndex[i]].children + i++ } this.pickerData = pickerData - if (!init) { - this.$refs.picker.setData(this.pickerData, this.pickerSelectedIndex) - this.$refs.picker.refresh() - for (let j = this.changedColumnIndex + 1; j < this.pickerSelectedIndex.length; j++) { - this.$refs.picker.scrollTo(j, this.pickerSelectedIndex[j]) - } - } } }, components: { From 23bf9322e344c34b6ef162a9dc40e202dd56edea Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 14:08:24 +0800 Subject: [PATCH 14/19] skip needless loop --- .../cascade-picker/cascade-picker.vue | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/cascade-picker/cascade-picker.vue b/src/components/cascade-picker/cascade-picker.vue index 2b29156b5..6f0088ed4 100644 --- a/src/components/cascade-picker/cascade-picker.vue +++ b/src/components/cascade-picker/cascade-picker.vue @@ -47,8 +47,7 @@ } }, created() { - this.changedColumnIndex = 0 - this.updatePickerData(true) + this.updatePickerData(0) }, methods: { show() { @@ -60,7 +59,7 @@ setData(data, selectedIndex) { this.cascadeData = data this.pickerSelectedIndex = selectedIndex - this.updatePickerData(true) + this.updatePickerData(0) }, _pickerSelect(selectedVal, selectedIndex, selectedText) { this.$emit(EVENT_SELECT, selectedVal, selectedIndex, selectedText) @@ -70,32 +69,33 @@ }, _pickerChange(i, newIndex) { if (newIndex !== this.pickerSelectedIndex[i]) { - this.changedColumnIndex = i this.pickerSelectedIndex.splice(i, 1, newIndex) - this.updatePickerData() + this.updatePickerData(i + 1) } this.$emit(EVENT_CHANGE, i, newIndex) }, - updatePickerData(init) { - const pickerData = [] + updatePickerData(refillColumnIndex) { let data = this.cascadeData let i = 0 while (Array.isArray(data) && data.length) { - let columnData = [] - data.forEach((item) => { - columnData.push({ - value: item.value, - text: item.text + if (i >= refillColumnIndex) { + let columnData = [] + data.forEach((item) => { + columnData.push({ + value: item.value, + text: item.text + }) }) - }) - pickerData[i] = columnData - this.pickerSelectedIndex[i] = init ? this.pickerSelectedIndex[i] || 0 : this.$refs.picker.refillColumn(i, columnData) + this.pickerData[i] = columnData + /* refillColumn could only be called after show() */ + this.pickerSelectedIndex[i] = refillColumnIndex === 0 ? this.pickerSelectedIndex[i] || 0 : this.$refs.picker.refillColumn(i, columnData) + } data = data[this.pickerSelectedIndex[i]].children i++ } - this.pickerData = pickerData + this.pickerData = this.pickerData.slice() } }, components: { From a189511dab26c4fb4a1aced3843ebbd351f71bc8 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 14:32:01 +0800 Subject: [PATCH 15/19] update setData --- example/pages/cascade-picker.vue | 5 ++++- src/components/cascade-picker/cascade-picker.vue | 6 ++++-- src/components/picker/picker.vue | 11 ++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/example/pages/cascade-picker.vue b/example/pages/cascade-picker.vue index 4aaafd7cf..421e202d8 100644 --- a/example/pages/cascade-picker.vue +++ b/example/pages/cascade-picker.vue @@ -76,8 +76,11 @@ this.datePicker.show() }, showSetDataPicker() { - this.setDataPicker.setData(cascadeData, [1, 1, 1]) + this.setDataPicker.setData(cascadeData) this.setDataPicker.show() + setTimeout(() => { + this.setDataPicker.setData(cityData, [1, 1, 0]) + }, 1000) }, selectHandle(selectedVal, selectedIndex, selectedText) { this.$createDialog({ diff --git a/src/components/cascade-picker/cascade-picker.vue b/src/components/cascade-picker/cascade-picker.vue index 6f0088ed4..719b6dbfa 100644 --- a/src/components/cascade-picker/cascade-picker.vue +++ b/src/components/cascade-picker/cascade-picker.vue @@ -56,7 +56,7 @@ hide() { this.$refs.picker.hide() }, - setData(data, selectedIndex) { + setData(data, selectedIndex = []) { this.cascadeData = data this.pickerSelectedIndex = selectedIndex this.updatePickerData(0) @@ -88,7 +88,9 @@ }) this.pickerData[i] = columnData /* refillColumn could only be called after show() */ - this.pickerSelectedIndex[i] = refillColumnIndex === 0 ? this.pickerSelectedIndex[i] || 0 : this.$refs.picker.refillColumn(i, columnData) + this.pickerSelectedIndex[i] = refillColumnIndex === 0 + ? (this.pickerSelectedIndex[i] < data.length - 1 ? this.pickerSelectedIndex[i] || 0 : 0) + : this.$refs.picker.refillColumn(i, columnData) } data = data[this.pickerSelectedIndex[i]].children diff --git a/src/components/picker/picker.vue b/src/components/picker/picker.vue index 1b393e248..9ac20c6ca 100644 --- a/src/components/picker/picker.vue +++ b/src/components/picker/picker.vue @@ -158,7 +158,16 @@ setData(data, selectedIndex) { this.pickerSelectedIndex = selectedIndex ? [...selectedIndex] : [] this.pickerData = data.slice() - this.dirty = true + if (this.isVisible) { + this.$nextTick(() => { + this.wheels.forEach((wheel, i) => { + wheel.refresh() + wheel.wheelTo(this.pickerSelectedIndex[i]) + }) + }) + } else { + this.dirty = true + } }, refill(datas) { let ret = [] From 2632cf585b005c598df3de976dcf100875a62997 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 14:58:06 +0800 Subject: [PATCH 16/19] update variable name + add default argument --- src/components/cascade-picker/cascade-picker.vue | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/cascade-picker/cascade-picker.vue b/src/components/cascade-picker/cascade-picker.vue index 719b6dbfa..395d8cbfa 100644 --- a/src/components/cascade-picker/cascade-picker.vue +++ b/src/components/cascade-picker/cascade-picker.vue @@ -47,7 +47,7 @@ } }, created() { - this.updatePickerData(0) + this.updatePickerData() }, methods: { show() { @@ -59,7 +59,7 @@ setData(data, selectedIndex = []) { this.cascadeData = data this.pickerSelectedIndex = selectedIndex - this.updatePickerData(0) + this.updatePickerData() }, _pickerSelect(selectedVal, selectedIndex, selectedText) { this.$emit(EVENT_SELECT, selectedVal, selectedIndex, selectedText) @@ -74,11 +74,11 @@ } this.$emit(EVENT_CHANGE, i, newIndex) }, - updatePickerData(refillColumnIndex) { + updatePickerData(fromColumn = 0) { let data = this.cascadeData let i = 0 while (Array.isArray(data) && data.length) { - if (i >= refillColumnIndex) { + if (i >= fromColumn) { let columnData = [] data.forEach((item) => { columnData.push({ @@ -88,8 +88,8 @@ }) this.pickerData[i] = columnData /* refillColumn could only be called after show() */ - this.pickerSelectedIndex[i] = refillColumnIndex === 0 - ? (this.pickerSelectedIndex[i] < data.length - 1 ? this.pickerSelectedIndex[i] || 0 : 0) + this.pickerSelectedIndex[i] = fromColumn === 0 + ? (this.pickerSelectedIndex[i] < data.length ? this.pickerSelectedIndex[i] || 0 : 0) : this.$refs.picker.refillColumn(i, columnData) } data = data[this.pickerSelectedIndex[i]].children From bb57101505d277c05106d038ede7e400ba87851d Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 17:28:41 +0800 Subject: [PATCH 17/19] add picker setData test --- test/unit/specs/picker.spec.js | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/test/unit/specs/picker.spec.js b/test/unit/specs/picker.spec.js index f2a975917..17432c0a6 100644 --- a/test/unit/specs/picker.spec.js +++ b/test/unit/specs/picker.spec.js @@ -156,7 +156,7 @@ describe('Picker', () => { }, 150) }) - it('should add warn log when sigle is false', () => { + it('should add warn log when single is true', () => { const app = new Vue() const originWarn = console.warn const msgs = [] @@ -173,6 +173,36 @@ describe('Picker', () => { console.warn = originWarn }) + it('setData when picker is invisible', function (done) { + this.timeout(10000) + vm = createPicker() + vm.setData([data1], [1]) + vm.show() + setTimeout(() => { + vm.confirm() + expect(vm.pickerSelectedIndex[0]).to.equal(1) + expect(vm.pickerSelectedVal[0]).to.equal(data1[1].value) + done() + }, 150) + }) + + it('setData when picker is visible', function (done) { + this.timeout(10000) + vm = createPicker({ + data: [data1] + }) + vm.show() + setTimeout(() => { + vm.setData([data2], [2]) + setTimeout(() => { + vm.confirm() + expect(vm.pickerSelectedIndex[0]).to.equal(2) + expect(vm.pickerSelectedVal[0]).to.equal(data2[2].value) + done() + }, 150) + }, 150) + }) + function createPicker(props = {}, events = {}) { return instantiateComponent(Vue, Picker, { props: props, From 28495d83da496712c84e541fed47c76a2c013ea6 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Wed, 13 Dec 2017 19:20:56 +0800 Subject: [PATCH 18/19] add cascade test --- example/data/cascade.js | 4 +- example/pages/cascade-picker.vue | 7 +- test/unit/specs/cascade-picker.spec.js | 99 ++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 test/unit/specs/cascade-picker.spec.js diff --git a/example/data/cascade.js b/example/data/cascade.js index e2f3d5247..b40350b5c 100644 --- a/example/data/cascade.js +++ b/example/data/cascade.js @@ -94,8 +94,8 @@ export const cascadeData = [ ] }, { - value: 'Tee', - text: 'Tee', + value: 'Tea', + text: 'Tea', children: [ { value: 1, diff --git a/example/pages/cascade-picker.vue b/example/pages/cascade-picker.vue index 421e202d8..7d3ad6f86 100644 --- a/example/pages/cascade-picker.vue +++ b/example/pages/cascade-picker.vue @@ -31,15 +31,10 @@ }) export default { - data() { - return { - data: cascadeData - } - }, mounted() { this.cascadePicker = this.$createCascadePicker({ title: 'Cascade Picker', - data: this.data, + data: cascadeData, selectedIndex: [1, 0, 0], onSelect: this.selectHandle, onCancel: this.cancelHandle diff --git a/test/unit/specs/cascade-picker.spec.js b/test/unit/specs/cascade-picker.spec.js new file mode 100644 index 000000000..f8ea4039b --- /dev/null +++ b/test/unit/specs/cascade-picker.spec.js @@ -0,0 +1,99 @@ +import Vue from 'vue2' +import CascadePicker from '@/modules/cascade-picker' +import instantiateComponent from '@/common/helpers/instantiate-component' +import { cascadeData } from 'example/data/cascade' + +describe('CascadePicker', () => { + let vm + + afterEach(() => { + if (vm) { + vm.$parent.destroy() + vm = null + } + }) + + it('use', () => { + Vue.use(CascadePicker) + expect(Vue.component(CascadePicker.name)) + .to.be.a('function') + }) + + it('should render correct contents', function () { + vm = createCascadePicker({ + data: cascadeData, + selectedIndex: [1, 1, 3] + }) + + const wheels = vm.$el.querySelectorAll('.cube-picker-wheel-wrapper > div') + expect(wheels.length) + .to.equal(3) + + const firstWheelItems = wheels[0].querySelectorAll('li') + expect(firstWheelItems.length) + .to.equal(3) + expect(firstWheelItems[1].textContent.trim()) + .to.equal('Drink') + + const secondWheelItems = wheels[1].querySelectorAll('li') + expect(secondWheelItems.length) + .to.equal(3) + expect(secondWheelItems[1].textContent.trim()) + .to.equal('Tea') + + const thirdWheelItems = wheels[2].querySelectorAll('li') + expect(thirdWheelItems.length) + .to.equal(4) + expect(thirdWheelItems[3].textContent.trim()) + .to.equal('Four') + }) + + it('should trigger events', function (done) { + this.timeout(10000) + + const selectHandle = sinon.spy() + const cancelHandle = sinon.spy() + const events = { + select: selectHandle, + cancel: cancelHandle + } + + vm = createCascadePicker({ + data: cascadeData + }, events) + + vm.show() + setTimeout(() => { + const cancelBtn = vm.$el.querySelector('.cube-picker-choose [data-action="cancel"]') + cancelBtn.click() + expect(cancelHandle) + .to.be.callCount(1) + + vm.show() + setTimeout(() => { + const confirmBtn = vm.$el.querySelector('.cube-picker-choose [data-action="confirm"]') + confirmBtn.click() + expect(selectHandle) + .to.be.callCount(1) + done() + }, 100) + }, 150) + }) + + it('setData', function () { + this.timeout(10000) + + vm = createCascadePicker() + + vm.setData(cascadeData, [1, 1, 1]) + // expect(vm.pickerData[2]) + // .to.deepEqual(cascadeData[1].children[1].children) + }) + + function createCascadePicker(props = {}, events = {}) { + return instantiateComponent(Vue, CascadePicker, { + props: props, + on: events + }) + } +}) From 382228d30c7b6b9f6e7e24e2d92b5db8414addd6 Mon Sep 17 00:00:00 2001 From: AmyFoxFN Date: Thu, 14 Dec 2017 12:44:15 +0800 Subject: [PATCH 19/19] add test change, setData --- example/pages/cascade-picker.vue | 5 ++- test/unit/specs/cascade-picker.spec.js | 46 ++++++++++++++++++++------ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/example/pages/cascade-picker.vue b/example/pages/cascade-picker.vue index 7d3ad6f86..00eaaca59 100644 --- a/example/pages/cascade-picker.vue +++ b/example/pages/cascade-picker.vue @@ -37,7 +37,10 @@ data: cascadeData, selectedIndex: [1, 0, 0], onSelect: this.selectHandle, - onCancel: this.cancelHandle + onCancel: this.cancelHandle, + onChange: () => { + console.log('change') + } }) this.cityPicker = this.$createCascadePicker({ diff --git a/test/unit/specs/cascade-picker.spec.js b/test/unit/specs/cascade-picker.spec.js index f8ea4039b..b7221749a 100644 --- a/test/unit/specs/cascade-picker.spec.js +++ b/test/unit/specs/cascade-picker.spec.js @@ -2,6 +2,7 @@ import Vue from 'vue2' import CascadePicker from '@/modules/cascade-picker' import instantiateComponent from '@/common/helpers/instantiate-component' import { cascadeData } from 'example/data/cascade' +import { dispatchSwipe } from '../utils/event' describe('CascadePicker', () => { let vm @@ -53,9 +54,11 @@ describe('CascadePicker', () => { const selectHandle = sinon.spy() const cancelHandle = sinon.spy() + const changeHandle = sinon.spy() const events = { select: selectHandle, - cancel: cancelHandle + cancel: cancelHandle, + change: changeHandle } vm = createCascadePicker({ @@ -64,19 +67,38 @@ describe('CascadePicker', () => { vm.show() setTimeout(() => { - const cancelBtn = vm.$el.querySelector('.cube-picker-choose [data-action="cancel"]') - cancelBtn.click() - expect(cancelHandle) - .to.be.callCount(1) + const wheels = vm.$el.querySelectorAll('.cube-picker-wheel-wrapper > div') + const firstWheelItems = wheels[0].querySelectorAll('li') + + dispatchSwipe(firstWheelItems[1], [ + { + pageX: firstWheelItems[1].offsetLeft + 10, + pageY: firstWheelItems[1].offsetTop + 10 + }, + { + pageX: 300, + pageY: 380 + } + ], 100) - vm.show() setTimeout(() => { + expect(changeHandle) + .to.be.callCount(1) + const confirmBtn = vm.$el.querySelector('.cube-picker-choose [data-action="confirm"]') confirmBtn.click() expect(selectHandle) .to.be.callCount(1) - done() - }, 100) + + vm.show() + setTimeout(() => { + const cancelBtn = vm.$el.querySelector('.cube-picker-choose [data-action="cancel"]') + cancelBtn.click() + expect(cancelHandle) + .to.be.callCount(1) + done() + }, 100) + }, 1000) }, 150) }) @@ -86,8 +108,12 @@ describe('CascadePicker', () => { vm = createCascadePicker() vm.setData(cascadeData, [1, 1, 1]) - // expect(vm.pickerData[2]) - // .to.deepEqual(cascadeData[1].children[1].children) + + /* expect vm.pickerData[2] equal to cascadeData[1].children[1].children */ + expect(vm.pickerData[2].length) + .to.equal(cascadeData[1].children[1].children.length) + expect(vm.pickerData[2][0].value) + .to.equal(cascadeData[1].children[1].children[0].value) }) function createCascadePicker(props = {}, events = {}) {