提交 e6bf9620 编写于 作者: A AmyFoxFN

[docs] cascade-picker: async

上级 3edf641b
......@@ -55,47 +55,47 @@ __Notice:__ Cause this component used create-api, so you should read [create-api
this.cascadePicker = this.$createCascadePicker({
title: 'Cascade Picker',
data: cascadeData,
selectedIndex: [1, 0, 0],
cancelTxt: 'Cancel',
confirmTxt: 'Confirm',
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
selectedIndex: [0, 1, 0],
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
},
methods: {
showCascadePicker() {
this.cascadePicker.show()
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
When the first column goes to `Fruit`, the data of second column are `Apple` and `Orange`. And so on, when the second column goes to on `Orange`, the data of third column are `Three` and `Four`.
- Province-city-area Picker
- Address Picker
For province-city-area picker, the only thing you need to do is constructing the cascading data.
For address picker, the only thing you need to do is constructing the cascading data.
```html
<cube-button @click="showCityPicker">City Picker</cube-button>
<cube-button @click="showAddressPicker">Address Picker</cube-button>
```
```js
import { provinceList, cityList, areaList } from 'example/data/area'
const cityData = provinceList
cityData.forEach(province => {
const addressData = provinceList
addressData.forEach(province => {
province.children = cityList[province.value]
province.children.forEach(city => {
city.children = areaList[city.value]
......@@ -104,115 +104,139 @@ __Notice:__ Cause this component used create-api, so you should read [create-api
export default {
mounted () {
this.cityPicker = this.$createCascadePicker({
this.addressPicker = this.$createCascadePicker({
title: 'City Picker',
data: cityData,
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
data: addressData,
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
},
methods: {
showCityPicker() {
this.cityPicker.show()
showAddressPicker() {
this.addressPicker.show()
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
- Date Picker
- Instance method `setData`
As same as province-city-area picker, you just need to construct the cascading data. Besides, we have written a [DatePicker component in example](https://github.com/didi/cube-ui/blob/dev/example/components/date-picker.vue), which could help you construct the cascading data with start date and end date.
You could use `setData` to reset the cascading data and selected index of `CascadePicker` instance no matter whether the picker is visible.
```html
<cube-button @click="showDatePicker">Date Picker</cube-button>
<cube-button @click="showSetDataPicker">SetData Picker</cube-button>
```
```js
import DatePicker from 'example/components/date-picker.vue'
createAPI(Vue, DatePicker, ['select', 'cancel'], false)
export default {
mounted () {
this.datePicker = this.$createDatePicker({
min: [2008, 8, 8],
max: [2020, 10, 20],
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
this.setDataPicker = this.$createCascadePicker({
title: 'Set Data',
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
},
methods: {
showDatePicker() {
this.datePicker.show()
showSetDataPicker() {
// setData when the picker is invisible.
this.setDataPicker.setData(cascadeData)
this.setDataPicker.show()
setTimeout(() => {
// setData when the picker is visible.
this.setDataPicker.setData(addressData, [1, 1, 0])
}, 1000)
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
- Instance method `setData`
- Async load data
You could use `setData` to reset the cascading data and selected index of `CascadePicker` instance no matter whether the picker is visible.
When the data is too large, it will be really hard to construct the whole cascade data tree at beginning. For this case, you could use the property `async` to enable async load data and update the data at the event `change`. Before the data is updated, we will block the confirm handler temporarily.
```html
<cube-button @click="showPicker">SetData Picker</cube-button>
<cube-button @click="showAsyncPicker">Async Load Data</cube-button>
```
```js
export default {
mounted () {
this.setDataPicker = this.$createCascadePicker({
title: 'Set Data',
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
this.asyncPicker = this.$createCascadePicker({
title: 'Async Load Data',
async: true,
data: asyncData,
selectedIndex: asyncSelectedIndex.slice(),
onSelect: this.selectHandle,
onCancel: this.cancelHandle,
onChange: this.asyncChangeHandle
})
},
methods: {
showSetDataPicker() {
/* setData when the picker is invisible */
this.setDataPicker.setData(cascadeData)
asyncChangeHandle(i, newIndex) {
if (newIndex !== asyncSelectedIndex[i]) {
asyncSelectedIndex[i] = newIndex
// If the first two column is changed, request the data for rest columns.
if (i < 2) {
// Mock async load.
setTimeout(() => {
if (i === 0) {
const current = asyncData[newIndex]
current.children = current.children || asyncCityList[current.value]
current.children[0].children = current.children[0].children || asyncAreaList[current.children[0].value]
asyncSelectedIndex[1] = 0
asyncSelectedIndex[2] = 0
}
this.setDataPicker.show()
setTimeout(() => {
/* setData when the picker is visible */
this.setDataPicker.setData(cityData, [1, 1, 0])
}, 1000)
if (i === 1) {
const current = asyncData[asyncSelectedIndex[0]].children[newIndex]
current.children = current.children || asyncAreaList[current.value]
asyncSelectedIndex[2] = 0
}
this.asyncPicker.setData(asyncData, asyncSelectedIndex)
}, 500)
}
}
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
......@@ -224,6 +248,7 @@ __Notice:__ Cause this component used create-api, so you should read [create-api
| - | - | - | - | - |
| data | the cascading data used to init option items | Array | [] | - |
| selectedIndex | the index of the selected item, corresponding content will be displayed when picker shows | Array | [] | [1] |
| async<sup>1.8.1</sup> | async load data | Boolean | false | - |
| title | title | String | '' | - |
| subtitle<sup>1.8.1</sup> | subtitle | String | '' | - |
| cancelTxt | the text of the cancel button | String | '取消' | - |
......
......@@ -55,38 +55,47 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请
this.cascadePicker = this.$createCascadePicker({
title: 'Cascade Picker',
data: cascadeData,
selectedIndex: [1, 0, 0],
cancelTxt: 'Cancel',
confirmTxt: 'Confirm',
onSelect: (selectedVal, selectedIndex, selectedText) => {
console.log('select', selectedVal, selectedIndex, selectedText)
},
onCancel: () => {
console.log('cancel')
}
selectedIndex: [0, 1, 0],
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
},
methods: {
showCascadePicker() {
this.cascadePicker.show()
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
当第一列选中`Fruit`时,第二列的选项是`Apple``Orange`。以此类推,当第二列选中`Orange`时,第三列的选项是`Three``Four`
- 省市区选择器
- 地址选择器
对于省市区选择器,只需要构造出级联选择器的数据结构传入就可以了。
对于地址选择器,只需要构造出级联选择器的数据结构传入就可以了。
```html
<cube-button @click="showCityPicker">City Picker</cube-button>
<cube-button @click="showAddressPicker">Address Picker</cube-button>
```
```js
import { provinceList, cityList, areaList } from 'example/data/area'
const cityData = provinceList
cityData.forEach(province => {
const addressData = provinceList
addressData.forEach(province => {
province.children = cityList[province.value]
province.children.forEach(city => {
city.children = areaList[city.value]
......@@ -95,114 +104,139 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请
export default {
mounted () {
this.cityPicker = this.$createCascadePicker({
this.addressPicker = this.$createCascadePicker({
title: 'City Picker',
data: cityData,
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
data: addressData,
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
},
methods: {
showCityPicker() {
this.cityPicker.show()
showAddressPicker() {
this.addressPicker.show()
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
- 日期选择器
- 实例方法 `setData`
日期选择器的原理也是一样,就是构造出级联选择器的数据结构。而且我们还在示例中提供一个[日期选择器组件](https://github.com/didi/cube-ui/blob/dev/example/components/date-picker.vue),可以传入起始日期和结束日期,帮你生成相应的级联树形数据结构。用法如下:
`setData`方法,用于重置`CascadePicker`实例的数据和选中的索引。
```html
<cube-button @click="showDatePicker">Date Picker</cube-button>
<cube-button @click="showSetDataPicker">SetData Picker</cube-button>
```
```js
import DatePicker from 'example/components/date-picker.vue'
createAPI(Vue, DatePicker, ['select', 'cancel'], false)
export default {
mounted () {
this.datePicker = this.$createDatePicker({
min: [2008, 8, 8],
max: [2020, 10, 20],
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
this.setDataPicker = this.$createCascadePicker({
title: 'Set Data',
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
},
methods: {
showDatePicker() {
this.datePicker.show()
showSetDataPicker() {
// setData when the picker is invisible.
this.setDataPicker.setData(cascadeData)
this.setDataPicker.show()
setTimeout(() => {
// setData when the picker is visible.
this.setDataPicker.setData(addressData, [1, 1, 0])
}, 1000)
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
```
- 实例方法 `setData`
- 异步加载数据
`setData`方法,用于重置`CascadePicker`实例的数据和选中的索引
当数据量太大时,可能难以在最开始就生成完整的级联数据树。这时,你可以配置 `async` 属性开启异步加载级联数据,在 `change` 事件时,去更新数据,并且在你更新完数据之前,用户点击确认会是无效的
```html
<cube-button @click="showPicker">SetData Picker</cube-button>
<cube-button @click="showAsyncPicker">Async Load Data</cube-button>
```
```js
export default {
mounted () {
this.setDataPicker = this.$createCascadePicker({
title: 'Set Data',
onSelect: (selectedVal, selectedIndex, selectedText) => {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/>
- index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
onCancel: () => {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
this.asyncPicker = this.$createCascadePicker({
title: 'Async Load Data',
async: true,
data: asyncData,
selectedIndex: asyncSelectedIndex.slice(),
onSelect: this.selectHandle,
onCancel: this.cancelHandle,
onChange: this.asyncChangeHandle
})
},
methods: {
showSetDataPicker() {
// setData when picker is invisible
this.setDataPicker.setData(cascadeData)
this.setDataPicker.show()
setTimeout(() => {
// setData when picker is visible
this.setDataPicker.setData(cityData, [1, 1, 0])
}, 1000)
asyncChangeHandle(i, newIndex) {
if (newIndex !== asyncSelectedIndex[i]) {
asyncSelectedIndex[i] = newIndex
// If the first two column is changed, request the data for rest columns.
if (i < 2) {
// Mock async load.
setTimeout(() => {
if (i === 0) {
const current = asyncData[newIndex]
current.children = current.children || asyncCityList[current.value]
current.children[0].children = current.children[0].children || asyncAreaList[current.children[0].value]
asyncSelectedIndex[1] = 0
asyncSelectedIndex[2] = 0
}
if (i === 1) {
const current = asyncData[asyncSelectedIndex[0]].children[newIndex]
current.children = current.children || asyncAreaList[current.value]
asyncSelectedIndex[2] = 0
}
this.asyncPicker.setData(asyncData, asyncSelectedIndex)
}, 500)
}
}
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
content: `Selected Item: <br/> - value: ${selectedVal.join(', ')} <br/> - index: ${selectedIndex.join(', ')} <br/> - text: ${selectedText.join(' ')}`,
icon: 'cubeic-alert'
}).show()
},
cancelHandle() {
this.$createToast({
type: 'correct',
txt: 'Picker canceled',
time: 1000
}).show()
}
}
}
......@@ -214,6 +248,7 @@ __注:__ 由于此组件基于 create-api 实现,所以在使用之前,请
| - | - | - | - | - |
| data | 级联选择器的树形数据,用于初始化选项 | Array | [] | - |
| selectedIndex | 被选中的索引值,拉起选择器后显示这个索引值对应的内容 | Array | [] | [1] |
| async<sup>1.8.1</sup> | 异步加载数据 | Boolean | false | - |
| title | 标题 | String | '' | - |
| subtitle<sup>1.8.1</sup> | 副标题 | String | '' | - |
| cancelTxt | 取消按钮文案 | String | '取消' | - |
......
......@@ -3,9 +3,9 @@
<div slot="content">
<cube-button-group>
<cube-button @click="showCascadePicker">Cascade Picker</cube-button>
<cube-button @click="showCityPicker">City Picker</cube-button>
<cube-button @click="showAddressPicker">Address Picker</cube-button>
<cube-button @click="showSetDataPicker">Set Data</cube-button>
<cube-button @click="showAsyncPicker">Async Cascade</cube-button>
<cube-button @click="showAsyncPicker">Async Load Data</cube-button>
</cube-button-group>
</div>
</cube-page>
......@@ -17,18 +17,22 @@
import { provinceList, cityList, areaList } from 'example/data/area'
import { cascadeData } from 'example/data/cascade'
const cityData = provinceList.slice()
cityData.forEach(province => {
const asyncProvinceList = provinceList.slice()
const asyncCityList = JSON.parse(JSON.stringify(cityList))
const asyncAreaList = JSON.parse(JSON.stringify(areaList))
const addressData = provinceList
addressData.forEach(province => {
province.children = cityList[province.value]
province.children.forEach(city => {
city.children = areaList[city.value]
})
})
const asyncData = provinceList.slice()
const asyncData = asyncProvinceList
const asyncSelectedIndex = [0, 0, 0]
asyncData[0].children = cityList[asyncData[0].value]
asyncData[0].children[0].children = areaList[asyncData[0].children[0].value]
asyncData[0].children = asyncCityList[asyncData[0].value]
asyncData[0].children[0].children = asyncAreaList[asyncData[0].children[0].value]
export default {
mounted() {
......@@ -36,18 +40,13 @@
title: 'Cascade Picker',
data: cascadeData,
selectedIndex: [0, 1, 0],
cancelTxt: 'Cancel',
confirmTxt: 'Confirm',
onSelect: this.selectHandle,
onCancel: this.cancelHandle,
onChange: () => {
console.log('change')
}
onCancel: this.cancelHandle
})
this.cityPicker = this.$createCascadePicker({
this.addressPicker = this.$createCascadePicker({
title: 'City Picker',
data: cityData,
data: addressData,
onSelect: this.selectHandle,
onCancel: this.cancelHandle
})
......@@ -59,53 +58,60 @@
})
this.asyncPicker = this.$createCascadePicker({
title: 'Async Cascade',
title: 'Async Load Data',
async: true,
data: asyncData,
selectedIndex: asyncSelectedIndex.slice(),
onSelect: this.selectHandle,
onCancel: this.cancelHandle,
onChange: (i, newIndex) => {
if (newIndex !== asyncSelectedIndex[i]) {
asyncSelectedIndex.splice(i, 1, newIndex)
if (i < 2) {
setTimeout(() => {
if (i === 0) {
const current = asyncData[newIndex]
current.children = current.children || cityList[current.value]
}
if (i === 1) {
const current = asyncData[asyncSelectedIndex[0]].children[newIndex]
current.children = current.children || areaList[current.value]
}
this.asyncPicker.setData(asyncData, asyncSelectedIndex)
}, 500)
}
}
}
onChange: this.asyncChangeHandle
})
},
methods: {
showCascadePicker() {
this.cascadePicker.show()
},
showCityPicker() {
this.cityPicker.show()
showAddressPicker() {
this.addressPicker.show()
},
showSetDataPicker() {
/* setData when the picker is invisible */
// setData when the picker is invisible.
this.setDataPicker.setData(cascadeData)
this.setDataPicker.show()
setTimeout(() => {
/* setData when the picker is visible */
this.setDataPicker.setData(cityData, [1, 1, 0])
// setData when the picker is visible.
this.setDataPicker.setData(addressData, [1, 1, 0])
}, 1000)
},
showAsyncPicker() {
this.asyncPicker.show()
},
asyncChangeHandle(i, newIndex) {
if (newIndex !== asyncSelectedIndex[i]) {
asyncSelectedIndex[i] = newIndex
// If the first two column is changed, request the data for rest columns.
if (i < 2) {
// Mock async load.
setTimeout(() => {
if (i === 0) {
const current = asyncData[newIndex]
current.children = current.children || asyncCityList[current.value]
current.children[0].children = current.children[0].children || asyncAreaList[current.children[0].value]
asyncSelectedIndex[1] = 0
asyncSelectedIndex[2] = 0
}
if (i === 1) {
const current = asyncData[asyncSelectedIndex[0]].children[newIndex]
current.children = current.children || asyncAreaList[current.value]
asyncSelectedIndex[2] = 0
}
this.asyncPicker.setData(asyncData, asyncSelectedIndex)
}, 500)
}
}
},
selectHandle(selectedVal, selectedIndex, selectedText) {
this.$createDialog({
type: 'warn',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册