diff --git a/example/App.vue b/example/App.vue
index 26788ed15..b18306415 100644
--- a/example/App.vue
+++ b/example/App.vue
@@ -56,6 +56,10 @@
path: '/picker',
text: 'Picker'
},
+ {
+ path: '/cascade-picker',
+ text: 'CascadePicker'
+ },
{
path: '/time-picker',
text: 'TimePicker'
diff --git a/example/components/date-picker.vue b/example/components/date-picker.vue
index 1bf976230..1c452bf21 100644
--- a/example/components/date-picker.vue
+++ b/example/components/date-picker.vue
@@ -1,13 +1,12 @@
-
-
+
diff --git a/example/pages/picker.vue b/example/pages/picker.vue
index 993fc229e..43dd42124 100644
--- a/example/pages/picker.vue
+++ b/example/pages/picker.vue
@@ -4,9 +4,7 @@
Picker
Multi-column Picker
- Linkage Picker
Use SetData
- Date Picker
Normal Time Picker
@@ -16,14 +14,11 @@
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 = []
diff --git a/src/index.js b/src/index.js
index c2c556666..0e354fada 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,6 +4,7 @@ import {
Scroll,
Popup,
TimePicker,
+ CascadePicker,
Dialog,
Tip,
Toast,
@@ -23,6 +24,7 @@ function install(Vue) {
Style,
Button,
TimePicker,
+ CascadePicker,
Dialog,
Tip,
Toast,
diff --git a/src/module.js b/src/module.js
index 507158380..6df0ae4c5 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 CascadePicker from './modules/cascade-picker'
import Scroll from './modules/scroll'
import BScroll from './modules/better-scroll'
@@ -28,6 +29,7 @@ export {
Popup,
Picker,
TimePicker,
+ 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/test/unit/specs/cascade-picker.spec.js b/test/unit/specs/cascade-picker.spec.js
new file mode 100644
index 000000000..b7221749a
--- /dev/null
+++ b/test/unit/specs/cascade-picker.spec.js
@@ -0,0 +1,125 @@
+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
+
+ 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 changeHandle = sinon.spy()
+ const events = {
+ select: selectHandle,
+ cancel: cancelHandle,
+ change: changeHandle
+ }
+
+ vm = createCascadePicker({
+ data: cascadeData
+ }, events)
+
+ vm.show()
+ setTimeout(() => {
+ 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)
+
+ 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)
+
+ 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)
+ })
+
+ it('setData', function () {
+ this.timeout(10000)
+
+ vm = createCascadePicker()
+
+ vm.setData(cascadeData, [1, 1, 1])
+
+ /* 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 = {}) {
+ return instantiateComponent(Vue, CascadePicker, {
+ props: props,
+ on: events
+ })
+ }
+})
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,