add cascader demo

pull/9/head
tjz 2018-03-04 16:02:46 +08:00
parent 6e8b5b9a20
commit 5cef22dbaa
14 changed files with 543 additions and 8 deletions

View File

@ -26,5 +26,6 @@
"vetur.format.js.InsertSpaceBeforeFunctionParenthesis": true,
"stylefmt.config": {
"fix": true
}
},
"editor.tabSize": 2
}

View File

@ -0,0 +1,53 @@
<cn>
#### 选择即改变
这种交互允许只选中父级选项。
</cn>
<us>
#### Change on select
Allow only select parent options.
</us>
```html
<template>
<a-cascader :options="options" @change="onChange" changeOnSelect />
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
}
},
methods: {
onChange(value) {
console.log(value);
}
}
}
</script>
```

View File

@ -0,0 +1,70 @@
<cn>
#### 自定义已选项
例如给最后一项加上邮编链接。
</cn>
<us>
#### Custom render
For instance, add an external link after the selected value.
</us>
```html
<template>
<a-cascader :options="options" :defaultValue="['zhejiang', 'hangzhou', 'xihu']" style="width: 100%">
<template slot="displayRender" slot-scope="props">
<span v-for="(label, index) in props.labels" :key="props.selectedOptions[index].value">
<span v-if="index === props.labels.length - 1">
{{label}} (<a @click="e => handleAreaClick(e, label, props.selectedOptions[index])">{{props.selectedOptions[index].code}}</a>)
</span>
<span v-else @click="onChange">
{{label}} /
</span>
</span>
</template>
</a-cascader>
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
code: 752100,
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
code: 453400,
}],
}],
}]
}
},
methods: {
onChange(value) {
console.log(value);
},
handleAreaClick(e, label, option) {
e.stopPropagation();
console.log('clicked', label, option);
},
}
}
</script>
```

View File

@ -0,0 +1,61 @@
<cn>
#### 可以自定义显示
切换按钮和结果分开。
</cn>
<us>
#### Custom trigger
Separate trigger button and result.
</us>
```html
<template>
<span>
{{text}}
&nbsp;
<a-cascader :options="options" @change="onChange">
<a href="#">Change city</a>
</a-cascader>
</span>
</template>
<script>
export default {
data() {
return {
text: 'Unselect',
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
}
},
methods: {
onChange(value, selectedOptions) {
this.text = selectedOptions.map(o => o.label).join(', ');
}
}
}
</script>
```

View File

@ -0,0 +1,53 @@
<cn>
#### 默认值
默认值通过数组的方式指定。
</cn>
<us>
#### Default value
Specifies default value by an array.
</us>
```html
<template>
<a-cascader :options="options" @change="onChange" :defaultValue="['zhejiang', 'hangzhou', 'xihu']" />
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
}
},
methods: {
onChange(value) {
console.log(value);
}
}
}
</script>
```

View File

@ -0,0 +1,54 @@
<cn>
#### 禁用选项
通过指定 options 里的 `disabled` 字段。
</cn>
<us>
#### Disabled option
Disable option by specifying the `disabled` property in `options`.
</us>
```html
<template>
<a-cascader :options="options" @change="onChange"/>
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
disabled: true,
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
}
},
methods: {
onChange(value) {
console.log(value);
}
}
}
</script>
```

View File

@ -0,0 +1,56 @@
<cn>
#### 移入展开
通过移入展开下级菜单,点击完成选择。
</cn>
<us>
#### Hover
Hover to expand sub menu, click to select option.
</us>
```html
<template>
<a-cascader :options="options" :displayRender="displayRender" expandTrigger="hover" @change="onChange" placeholder="Please select" />
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
}
},
methods: {
onChange(value) {
console.log(value);
},
displayRender({ labels }) {
return labels[labels.length - 1];
}
}
}
</script>
```

View File

View File

@ -0,0 +1,58 @@
<cn>
#### 动态加载选项
使用 `loadData` 实现动态加载选项。
> 注意:`loadData` 与 `showSearch` 无法一起使用。
</cn>
<us>
#### Load Options Lazily
Load options lazily with `loadData`.
> Note: `loadData` cannot work with `showSearch`.
</us>
```html
<template>
<a-cascader :options="options" @change="onChange" :loadData="loadData" placeholder="Please select" changeOnSelect/>
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
isLeaf: false,
}, {
value: 'jiangsu',
label: 'Jiangsu',
isLeaf: false,
}]
}
},
methods: {
onChange(value) {
console.log(value);
},
loadData(selectedOptions) {
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
// load options lazily
setTimeout(() => {
targetOption.loading = false;
targetOption.children = [{
label: `${targetOption.label} Dynamic 1`,
value: 'dynamic1',
}, {
label: `${targetOption.label} Dynamic 2`,
value: 'dynamic2',
}];
this.options = [...this.options]
}, 1000);
}
}
}
</script>
```

View File

@ -0,0 +1,59 @@
<cn>
#### 搜索
可以直接搜索选项并选择。
> `Cascader[showSearch]` 暂不支持服务端搜索,更多信息见 [#5547](https://github.com/ant-design/ant-design/issues/5547)
</cn>
<us>
#### Search
Search and select options directly.
> Now, `Cascader[showSearch]` doesn't support search on server, more info [#5547](https://github.com/ant-design/ant-design/issues/5547)
</us>
```html
<template>
<a-cascader :options="options" :showSearch="true" @change="onChange" placeholder="Please select" />
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}, {
value: 'xiasha',
label: 'Xia Sha',
disabled: true,
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua men',
}],
}],
}]
}
},
methods: {
onChange(value, selectedOptions) {
console.log(value, selectedOptions);
}
}
}
</script>
```

View File

@ -0,0 +1,57 @@
<cn>
#### 大小
不同大小的级联选择器。
</cn>
<us>
#### Size
Cascade selection box of different sizes.
</us>
```html
<template>
<div>
<a-cascader size="large" :options="options" @change="onChange" /><br /><br />
<a-cascader :options="options" @change="onChange" /><br /><br />
<a-cascader size="small" :options="options" @change="onChange" /><br /><br />
</div>
</template>
<script>
export default {
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}]
}
},
methods: {
onChange(value) {
console.log(value);
}
}
}
</script>
```

View File

@ -80,11 +80,15 @@ function defaultSortFilteredOption (a, b, inputValue) {
return a.findIndex(callback) - b.findIndex(callback)
}
const defaultDisplayRender = (label) => label.join(' / ')
const defaultDisplayRender = ({ labels }) => labels.join(' / ')
export default {
mixins: [BaseMixin],
props: CascaderProps,
model: {
prop: 'value',
event: 'change',
},
data () {
this.cachedOptions = []
const { value, defaultValue, popupVisible, showSearch, options, changeOnSelect, flattenTree } = this
@ -181,14 +185,15 @@ export default {
},
getLabel () {
const { options, displayRender = defaultDisplayRender } = this
const { options, $scopedSlots } = this
const displayRender = this.displayRender || $scopedSlots.displayRender || defaultDisplayRender
const value = this.sValue
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value
const selectedOptions = arrayTreeFilter(options,
(o, level) => o.value === unwrappedValue[level],
)
const label = selectedOptions.map(o => o.label)
return displayRender(label, selectedOptions)
const labels = selectedOptions.map(o => o.label)
return displayRender({ labels, selectedOptions })
},
clearSelection (e) {
@ -295,6 +300,7 @@ export default {
'renderFilteredOption',
'sortFilteredOption',
'notFoundContent',
'defaultValue',
])
let options = this.options
@ -342,10 +348,13 @@ export default {
<span
class={pickerCls}
>
<span class={`${prefixCls}-picker-label`}>
{ showSearch ? <span class={`${prefixCls}-picker-label`}>
{this.getLabel()}
</span>
</span> : null}
<Input {...inputProps}/>
{ !showSearch ? <span class={`${prefixCls}-picker-label`}>
{this.getLabel()}
</span> : null}
{clearIcon}
<Icon type='down' class={arrowCls} />
</span>

View File

@ -66,6 +66,10 @@ export default {
expandTrigger: PropTypes.string.def('click'),
},
mixins: [BaseMixin],
model: {
prop: 'value',
event: 'change',
},
data () {
let initialValue = []
const { value, defaultValue, popupVisible } = this

View File

@ -45,7 +45,7 @@ export default {
on: {
click: onSelect,
},
key: option.value,
key: option.value.toString(),
}
let menuItemCls = `${prefixCls}-menu-item`
const hasChildren = option.children && option.children.length > 0