Commit 0643460b authored by 杨奕's avatar 杨奕 Committed by baiyaaaaa

Cascader: update (#2845)

* Cascader: update

* Cascader: add tests

* Cascader: move flatOptions and add debounce
parent 3f64571f
...@@ -185,7 +185,8 @@ ...@@ -185,7 +185,8 @@
panel_js: 3, panel_js: 3,
panel_css: 1 panel_css: 1
}; };
const form = document.createElement('form'); const form = document.getElementById('fiddle-form') || document.createElement('form');
form.innerHTML = '';
const node = document.createElement('textarea'); const node = document.createElement('textarea');
form.method = 'post'; form.method = 'post';
...@@ -197,6 +198,9 @@ ...@@ -197,6 +198,9 @@
node.value = data[name].toString(); node.value = data[name].toString();
form.appendChild(node.cloneNode()); form.appendChild(node.cloneNode());
} }
form.setAttribute('id', 'fiddle-form');
form.style.display = 'none';
document.body.appendChild(form);
form.submit(); form.submit();
} }
......
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options2: [{
label: 'California',
cities: []
}, {
label: 'Florida',
cities: []
}],
props: {
value: 'label',
children: 'cities'
},
options: [{ options: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout'
}], }, {
}], value: 'color',
}], label: 'Color'
optionsWithDisabled: [{ }, {
value: 'zhejiang', value: 'typography',
label: 'Zhejiang', label: 'Typography'
disabled: true, }, {
children: [{ value: 'icon',
value: 'hangzhou', label: 'Icon'
label: 'Hangzhou', }, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{ children: [{
value: 'xihu', value: 'alert',
label: 'West Lake', label: 'Alert'
}], }, {
value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'menu',
label: 'Jiang Bei', label: 'NavMenu'
}], }, {
}], value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog'
}, {
value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, { }, {
value: 'jiangsu', value: 'resource',
label: 'Jiangsu', label: 'Resource',
children: [{ children: [{
value: 'nanjing', value: 'axure',
label: 'Nanjing', label: 'Axure Components'
children: [{ }, {
value: 'zhonghuamen', value: 'sketch',
label: 'Zhong Hua Men', label: 'Sketch Templates'
}], }, {
}], value: 'docs',
label: 'Design Documentation'
}]
}], }],
optionsWithDisabled: [],
selectedOptions: [], selectedOptions: [],
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen'] selectedOptions2: [],
selectedOptions3: ['component', 'data', 'tag']
}; };
}, },
created() {
this.optionsWithDisabled = JSON.parse(JSON.stringify(this.options));
this.optionsWithDisabled[0].disabled = true;
},
mounted() {
this.$nextTick(() => {
const demos = document.querySelectorAll('.source');
demos[0].style.padding = '0';
demos[demos.length - 1].style.padding = '0';
});
},
methods: { methods: {
handleItemChange(val) {
console.log('active item:', val);
setTimeout(_ => {
if (val.indexOf('California') > -1 && !this.options2[0].cities.length) {
this.options2[0].cities = [{
label: 'Los Angeles'
}];
} else if (val.indexOf('Florida') > -1 && !this.options2[1].cities.length) {
this.options2[1].cities = [{
label: 'Orlando'
}];
}
}, 300);
},
handleChange(value) { handleChange(value) {
console.log(value); console.log(value);
} }
...@@ -75,67 +247,232 @@ ...@@ -75,67 +247,232 @@
}; };
</script> </script>
<style>
.demo-cascader {
.el-cascader {
width: 222px;
}
}
.demo-cascader-size {
.el-cascader {
vertical-align: top;
margin-right: 15px;
}
}
</style>
## Cascader ## Cascader
It's used to select from a set of associated data set. Such as province/city/district, company level, and categories. If the options have a clear hierarchical structure, Cascader can be used to view and select them.
### Basic usage ### Basic usage
:::demo There are two ways to expand child option items.
:::demo Assigning the `options` attribute to an array of options renders a Cascader. The `expand-trigger` attribute defines how child options are expanded. This example also demonstrates the `change` event, whose parameter is the value of Cascader, an array made up of the values of each selected level.
```html ```html
<el-cascader <div class="block">
placeholder="Please select" <span class="demonstration">Child options expand when clicked (default)</span>
:options="options" <el-cascader
v-model="selectedOptions" :options="options"
@change="handleChange" v-model="selectedOptions"
></el-cascader> @change="handleChange">
</el-cascader>
</div>
<div class="block">
<span class="demonstration">Child options expand when hovered</span>
<el-cascader
expand-trigger="hover"
:options="options"
v-model="selectedOptions2"
@change="handleChange">
</el-cascader>
</div>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{
value: 'layout',
label: 'Layout'
}, {
value: 'color',
label: 'Color'
}, {
value: 'typography',
label: 'Typography'
}, {
value: 'icon',
label: 'Icon'
}, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert'
}, {
value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu'
}, {
value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{ children: [{
value: 'zhonghuamen', value: 'dialog',
label: 'Zhong Hua Men', label: 'Dialog'
}], }, {
}], value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, {
value: 'resource',
label: 'Resource',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'docs',
label: 'Design Documentation'
}]
}], }],
selectedOptions: [] selectedOptions: []
}; };
...@@ -152,46 +489,212 @@ It's used to select from a set of associated data set. Such as province/city/dis ...@@ -152,46 +489,212 @@ It's used to select from a set of associated data set. Such as province/city/dis
### Disabled option ### Disabled option
:::demo Disable an option by setting a `disabled` field in the option object.
:::demo In this example, the first item in `options` array has a `disabled: true` field, so it is disabled. By default, Cascader checks the `disabled` field in each option object; if you are using another field name to indicate whether an option is disabled, you can assign it in the `props` attribute (see the API table below for details). And of course, field name `value`, `label` and `children` can also be customized in the same way.
```html ```html
<el-cascader <el-cascader
placeholder="Please select"
:options="optionsWithDisabled" :options="optionsWithDisabled"
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
optionsWithDisabled: [{ optionsWithDisabled: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
disabled: true, disabled: true,
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{
value: 'layout',
label: 'Layout'
}, {
value: 'color',
label: 'Color'
}, {
value: 'typography',
label: 'Typography'
}, {
value: 'icon',
label: 'Icon'
}, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{ children: [{
value: 'zhonghuamen', value: 'alert',
label: 'Zhong Hua Men', label: 'Alert'
}], }, {
}], value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu'
}, {
value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog'
}, {
value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, {
value: 'resource',
label: 'Resource',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'docs',
label: 'Design Documentation'
}]
}] }]
}; };
} }
...@@ -200,50 +703,215 @@ It's used to select from a set of associated data set. Such as province/city/dis ...@@ -200,50 +703,215 @@ It's used to select from a set of associated data set. Such as province/city/dis
``` ```
::: :::
### Default Value ### Display only the last level
:::demo default value is assigned by an array type value. The input can display only the last level instead of all levels.
:::demo The `show-all-levels` attribute defines if all levels are displayed. If it is `false`, only the last level is displayed.
```html ```html
<el-cascader <el-cascader
placeholder="Please select" :options="options"
:options="options" :show-all-levels="false"
v-model="selectedOptions2"
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout'
}], }, {
}], value: 'color',
}], label: 'Color'
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen'] }, {
value: 'typography',
label: 'Typography'
}, {
value: 'icon',
label: 'Icon'
}, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert'
}, {
value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu'
}, {
value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog'
}, {
value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, {
value: 'resource',
label: 'Resource',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'docs',
label: 'Design Documentation'
}]
}]
}; };
} }
}; };
...@@ -251,60 +919,214 @@ It's used to select from a set of associated data set. Such as province/city/dis ...@@ -251,60 +919,214 @@ It's used to select from a set of associated data set. Such as province/city/dis
``` ```
::: :::
### Size ### With default value
:::demo :::demo The default value can be defined with an array.
```html ```html
<div class="demo-cascader-size"> <el-cascader
<el-cascader :options="options"
placeholder="Please select" v-model="selectedOptions3"
:options="options" ></el-cascader>
size="large"
></el-cascader>
<el-cascader
placeholder="Please select"
:options="options"
></el-cascader>
<el-cascader
placeholder="Please select"
:options="options"
size="small"
></el-cascader>
</div>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout'
}], }, {
}], value: 'color',
}] label: 'Color'
}, {
value: 'typography',
label: 'Typography'
}, {
value: 'icon',
label: 'Icon'
}, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert'
}, {
value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu'
}, {
value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog'
}, {
value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, {
value: 'resource',
label: 'Resource',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'docs',
label: 'Design Documentation'
}]
}],
selectedOptions3: ['component', 'data', 'tag']
}; };
} }
}; };
...@@ -312,50 +1134,214 @@ It's used to select from a set of associated data set. Such as province/city/dis ...@@ -312,50 +1134,214 @@ It's used to select from a set of associated data set. Such as province/city/dis
``` ```
::: :::
### Hover to expand ### Change on select
Hover to expand the next level options, click to select option. Parent options can also be selected.
:::demo :::demo By default only the options in the last level can be selected. By assigning `change-on-select` to `true`, options in parent levels can also be selected.
```html ```html
<el-cascader <el-cascader
placeholder="Please select"
:options="options" :options="options"
expand-trigger="hover" change-on-select
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout'
}], }, {
}], value: 'color',
label: 'Color'
}, {
value: 'typography',
label: 'Typography'
}, {
value: 'icon',
label: 'Icon'
}, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert'
}, {
value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu'
}, {
value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog'
}, {
value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, {
value: 'resource',
label: 'Resource',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'docs',
label: 'Design Documentation'
}]
}] }]
}; };
} }
...@@ -364,102 +1350,279 @@ Hover to expand the next level options, click to select option. ...@@ -364,102 +1350,279 @@ Hover to expand the next level options, click to select option.
``` ```
::: :::
### Change on select ### Dynamically load child options
Allow only select parent options. Load child options when their parent option is clicked or hovered over.
:::demo :::demo In this example, the options array does not have data of cities when initialized. With the `active-item-change` event, you can load the cities of a specific state dynamically. Besides, this example also demonstrates how `props` is used.
```html ```html
<el-cascader <el-cascader
placeholder="Please select" :options="options2"
:options="options" @active-item-change="handleItemChange"
change-on-select :props="props"
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options2: [{
value: 'zhejiang', label: 'California',
label: 'Zhejiang', cities: []
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}, {
value: 'ningbo',
label: 'NingBo',
children: [{
value: 'jiangbei',
label: 'Jiang Bei',
}],
}],
}, { }, {
value: 'jiangsu', label: 'Florida',
label: 'Jiangsu', cities: []
children: [{ }],
value: 'nanjing', props: {
label: 'Nanjing', value: 'label',
children: [{ children: 'cities'
value: 'zhonghuamen', }
label: 'Zhong Hua Men',
}],
}],
}]
}; };
},
methods: {
handleItemChange(val) {
console.log('active item:', val);
setTimeout(_ => {
if (val.indexOf('California') > -1 && !this.options2[0].cities.length) {
this.options2[0].cities = [{
label: 'Los Angeles'
}];
} else if (val.indexOf('Florida') > -1 && !this.options2[1].cities.length) {
this.options2[1].cities = [{
label: 'Orlando'
}];
}
}, 300);
}
} }
}; };
</script> </script>
``` ```
::: :::
### Search ### Filterable
Search and select options directly. Search and select options with a keyword.
:::demo :::demo Adding `filterable` to `el-cascader` enables filtering
```html ```html
<el-cascader <div class="block">
placeholder="Please select" <span class="demonstration">Only options of the last level can be selected</span>
:options="options" <el-cascader
filterable placeholder="Try searching: Guide"
></el-cascader> :options="options"
filterable
></el-cascader>
</div>
<div class="block">
<span class="demonstration">Options of all levels can be selected</span>
<el-cascader
placeholder="Try searching: Guide"
:options="options"
filterable
change-on-select
></el-cascader>
</div>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'guide',
label: 'Zhejiang', label: 'Guide',
children: [{ children: [{
value: 'hangzhou', value: 'disciplines',
label: 'Hangzhou', label: 'Disciplines',
children: [{ children: [{
value: 'xihu', value: 'consistency',
label: 'West Lake', label: 'Consistency'
}], }, {
value: 'feedback',
label: 'Feedback'
}, {
value: 'efficiency',
label: 'Efficiency'
}, {
value: 'controllability',
label: 'Controllability'
}]
}, { }, {
value: 'ningbo', value: 'navigation',
label: 'NingBo', label: 'Navigation',
children: [{ children: [{
value: 'jiangbei', value: 'side nav',
label: 'Jiang Bei', label: 'Side Navigation'
}], }, {
}], value: 'top nav',
label: 'Top Navigation'
}]
}]
}, { }, {
value: 'jiangsu', value: 'component',
label: 'Jiangsu', label: 'Component',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout'
}], }, {
}], value: 'color',
label: 'Color'
}, {
value: 'typography',
label: 'Typography'
}, {
value: 'icon',
label: 'Icon'
}, {
value: 'button',
label: 'Button'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio'
}, {
value: 'checkbox',
label: 'Checkbox'
}, {
value: 'input',
label: 'Input'
}, {
value: 'input-number',
label: 'InputNumber'
}, {
value: 'select',
label: 'Select'
}, {
value: 'cascader',
label: 'Cascader'
}, {
value: 'switch',
label: 'Switch'
}, {
value: 'slider',
label: 'Slider'
}, {
value: 'time-picker',
label: 'TimePicker'
}, {
value: 'date-picker',
label: 'DatePicker'
}, {
value: 'datetime-picker',
label: 'DateTimePicker'
}, {
value: 'upload',
label: 'Upload'
}, {
value: 'rate',
label: 'Rate'
}, {
value: 'form',
label: 'Form'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table'
}, {
value: 'tag',
label: 'Tag'
}, {
value: 'progress',
label: 'Progress'
}, {
value: 'tree',
label: 'Tree'
}, {
value: 'pagination',
label: 'Pagination'
}, {
value: 'badge',
label: 'Badge'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert'
}, {
value: 'loading',
label: 'Loading'
}, {
value: 'message',
label: 'Message'
}, {
value: 'message-box',
label: 'MessageBox'
}, {
value: 'notification',
label: 'Notification'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu'
}, {
value: 'tabs',
label: 'Tabs'
}, {
value: 'breadcrumb',
label: 'Breadcrumb'
}, {
value: 'dropdown',
label: 'Dropdown'
}, {
value: 'steps',
label: 'Steps'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog'
}, {
value: 'tooltip',
label: 'Tooltip'
}, {
value: 'popover',
label: 'Popover'
}, {
value: 'card',
label: 'Card'
}, {
value: 'carousel',
label: 'Carousel'
}, {
value: 'collapse',
label: 'Collapse'
}]
}]
}, {
value: 'resource',
label: 'Resource',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'docs',
label: 'Design Documentation'
}]
}] }]
}; };
} }
...@@ -471,17 +1634,30 @@ Search and select options directly. ...@@ -471,17 +1634,30 @@ Search and select options directly.
### Attributes ### Attributes
| Attribute | Description | Type | Options | Default| | Attribute | Description | Type | Options | Default|
|---------- |-------------------- |---------|------------- |-------- | |---------- |-------------------- |---------|------------- |-------- |
| options | data source of the options | array | — | — | | options | data of the options | array | — | — |
| value | selected value | array | — | — | | props | configuration options, see the following table | object | — | — |
| popper-class | className of popup overlay | string | — | — | | value | selected value | array | — | — |
| placeholder | input placeholder | string | — | — | | popper-class | custom class name for Cascader's dropdown | string | — | — |
| disabled | 是否禁用 | boolean | — | false | | placeholder | input placeholder | string | — | Select |
| clearable | whether allow clear | boolean | — | false | | disabled | whether Cascader is disabled | boolean | — | false |
| expand-trigger | trigger mode of expandind the current item | string | click / hover | 'click' | | clearable | whether selected value can be cleared | boolean | — | false |
| expand-trigger | trigger mode of expanding current item | string | click / hover | click |
| show-all-levels | whether to display all levels of the selected value in the input | boolean | — | true |
| filterable | whether the options can be searched | boolean | — | — | | filterable | whether the options can be searched | boolean | — | — |
| size | size | string | large / small / mini | — | | debounce | debounce delay when typing filter keyword, in millisecond | number | — | 300 |
| change-on-select | whether selecting an option of any level is permitted | boolean | — | false |
| size | size of Input | string | large / small / mini | — |
### props
| Attribute | Description | Type | Accepted Values | Default |
| --------- | ----------------- | ------ | ------ | ------ |
| label | specify which key of option object is used as the option's label | string | — | — |
| value | specify which key of option object is used as the option's value | string | — | — |
| children | specify which key of option object is used as the option's child options | string | — | — |
| disabled | specify which key of option object indicates if the option is disabled | string | — | — |
### Events ### Events
| Event Name | Description | Parameters | | Event Name | Description | Parameters |
|---------- |-------- |---------- | |---------- |-------- |---------- |
| change | triggers when the binding value changes | value | | change | triggers when the binding value changes | value |
\ No newline at end of file | active-item-change | triggers when active option changes, only works when `change-on-select` is `false` | an array of active options |
\ No newline at end of file
...@@ -462,7 +462,7 @@ Display options in groups. ...@@ -462,7 +462,7 @@ Display options in groups.
You can filter options for your desired ones. You can filter options for your desired ones.
:::demo Adding `filterable` to `el-select` enables filtering. By default, Select will find all the options whose `label` attribute contains the input value. If you prefer other filtering strategies, you can pass the `filter-method`. `filter-method` is a `Function` that gets called when the input value changed, and its parameter is the current input value. :::demo Adding `filterable` to `el-select` enables filtering. By default, Select will find all the options whose `label` attribute contains the input value. If you prefer other filtering strategies, you can pass the `filter-method`. `filter-method` is a `Function` that gets called when the input value changes, and its parameter is the current input value.
```html ```html
<template> <template>
<el-select v-model="value8" filterable placeholder="Select"> <el-select v-model="value8" filterable placeholder="Select">
......
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options2: [{
label: '江苏',
cities: []
}, {
label: '浙江',
cities: []
}],
props: {
value: 'label',
children: 'cities'
},
options: [{ options: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake' label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}] }]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei' label: '侧向导航'
}, {
value: 'dingbudaohang',
label: '顶部导航'
}] }]
}] }]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men' label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}] }]
}] }, {
}], value: 'form',
optionsWithDisabled: [{ label: 'Form',
value: 'zhejiang', children: [{
label: 'Zhejiang', value: 'radio',
disabled: true, label: 'Radio 单选框'
children: [{ }, {
value: 'hangzhou', value: 'checkbox',
label: 'Hangzhou', label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{ children: [{
value: 'xihu', value: 'menu',
label: 'West Lake' label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}] }]
}, { }, {
value: 'ningbo', value: 'others',
label: 'NingBo', label: 'Others',
children: [{ children: [{
value: 'jiangbei', value: 'dialog',
label: 'Jiang Bei' label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}] }]
}] }]
}, { }, {
value: 'jiangsu', value: 'ziyuan',
label: 'Jiangsu', label: '资源',
children: [{ children: [{
value: 'nanjing', value: 'axure',
label: 'Nanjing', label: 'Axure Components'
children: [{ }, {
value: 'zhonghuamen', value: 'sketch',
label: 'Zhong Hua Men' label: 'Sketch Templates'
}] }, {
value: 'jiaohu',
label: '组件交互文档'
}] }]
}], }],
optionsWithDisabled: [],
selectedOptions: [], selectedOptions: [],
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen'] selectedOptions2: [],
selectedOptions3: ['zujian', 'data', 'tag']
}; };
}, },
created() {
this.optionsWithDisabled = JSON.parse(JSON.stringify(this.options));
this.optionsWithDisabled[0].disabled = true;
},
mounted() {
this.$nextTick(() => {
const demos = document.querySelectorAll('.source');
demos[0].style.padding = '0';
demos[demos.length - 1].style.padding = '0';
});
},
methods: { methods: {
handleItemChange(val) {
console.log('active item:', val);
setTimeout(_ => {
if (val.indexOf('江苏') > -1 && !this.options2[0].cities.length) {
this.options2[0].cities = [{
label: '南京'
}];
} else if (val.indexOf('浙江') > -1 && !this.options2[1].cities.length) {
this.options2[1].cities = [{
label: '杭州'
}];
}
}, 300);
},
handleChange(value) { handleChange(value) {
console.log(value); console.log(value);
} }
...@@ -87,57 +259,251 @@ ...@@ -87,57 +259,251 @@
margin-right: 15px; margin-right: 15px;
} }
} }
.demo-cascader .block {
padding: 30px 0;
text-align: center;
border-right: solid 1px #EFF2F6;
float: left;
width: 50%;
box-sizing: border-box;
&:last-child {
border-right: none;
}
}
.demo-cascader .demonstration {
display: block;
color: #8492a6;
font-size: 14px;
margin-bottom: 20px;
}
</style> </style>
## 级联选择 ## Cascader 级联选择器
需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等 当一个数据集合有清晰的层级结构时,可通过级联选择器逐级查看并选择
从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。 ### 基础用法
### 基本使用 有两种触发子菜单的方式
:::demo :::demo 只需为 Cascader 的`options`属性指定选项数组即可渲染出一个级联选择器。通过`expand-trigger`可以定义展开子级菜单的触发方式。本例还展示了`change`事件,它的参数为 Cascader 的绑定值:一个由各级菜单的值所组成的数组。
```html ```html
<el-cascader <div class="block">
placeholder="请选择" <span class="demonstration">默认 click 触发子菜单</span>
:options="options" <el-cascader
v-model="selectedOptions" :options="options"
@change="handleChange" v-model="selectedOptions"
></el-cascader> @change="handleChange">
</el-cascader>
</div>
<div class="block">
<span class="demonstration">hover 触发子菜单</span>
<el-cascader
expand-trigger="hover"
:options="options"
v-model="selectedOptions2"
@change="handleChange">
</el-cascader>
</div>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake', label: '一致'
}], }, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei', label: '侧向导航'
}], }, {
}], value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{ children: [{
value: 'zhonghuamen', value: 'table',
label: 'Zhong Hua Men', label: 'Table 表格'
}], }, {
}], value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}], }],
selectedOptions: [] selectedOptions: []
}; };
...@@ -154,48 +520,212 @@ ...@@ -154,48 +520,212 @@
### 禁用选项 ### 禁用选项
通过在数据源中设置 `disabled` 字段来声明该选项禁用的 通过在数据源中设置 `disabled` 字段来声明该选项禁用的
:::demo :::demo 本例中,`options`指定的数组中的第一个元素含有`disabled: true`键值对,因此是禁用的。在默认情况下,Cascader 会检查数据中每一项的`disabled`字段是否为`true`,如果你的数据中表示禁用含义的字段名不为`disabled`,可以通过`props`属性来指定(详见下方 API 表格)。当然,`value``label``children`这三个字段名也可以通过同样的方式指定。
```html ```html
<el-cascader <el-cascader
placeholder="请选择"
:options="optionsWithDisabled" :options="optionsWithDisabled"
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
optionsWithDisabled: [{ optionsWithDisabled: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
disabled: true, disabled: true,
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake', label: '一致'
}], }, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei', label: '侧向导航'
}], }, {
}], value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{ children: [{
value: 'zhonghuamen', value: 'dialog',
label: 'Zhong Hua Men', label: 'Dialog 对话框'
}], }, {
}], value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}] }]
}; };
} }
...@@ -204,50 +734,215 @@ ...@@ -204,50 +734,215 @@
``` ```
::: :::
### 默认值 ### 仅显示最后一级
:::demo 默认值通过数组的方式指定。 可以仅在输入框中显示选中项最后一级的标签,而不是选中项所在的完整路径。
:::demo 属性`show-all-levels`定义了是否显示完整的路径,将其赋值为`false`则仅显示最后一级
```html ```html
<el-cascader <el-cascader
placeholder="请选择"
:options="options" :options="options"
v-model="selectedOptions2" :show-all-levels="false"
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake', label: '一致'
}], }, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei', label: '侧向导航'
}], }, {
}], value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout 布局'
}], }, {
}], value: 'color',
}], label: 'Color 色彩'
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen'] }, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}]
}; };
} }
}; };
...@@ -255,60 +950,214 @@ ...@@ -255,60 +950,214 @@
``` ```
::: :::
### 尺寸 ### 默认值
:::demo 提供三种尺寸的级联选择器 :::demo 默认值通过数组的方式指定。
```html ```html
<div class="demo-cascader-size"> <el-cascader
<el-cascader :options="options"
placeholder="请选择" v-model="selectedOptions3"
:options="options" ></el-cascader>
size="large"
></el-cascader>
<el-cascader
placeholder="请选择"
:options="options"
></el-cascader>
<el-cascader
placeholder="请选择"
:options="options"
size="small"
></el-cascader>
</div>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake', label: '一致'
}], }, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei', label: '侧向导航'
}], }, {
}], value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{ children: [{
value: 'zhonghuamen', value: 'layout',
label: 'Zhong Hua Men', label: 'Layout 布局'
}], }, {
}], value: 'color',
}] label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}],
selectedOptions3: ['zujian', 'data', 'tag']
}; };
} }
}; };
...@@ -316,50 +1165,214 @@ ...@@ -316,50 +1165,214 @@
``` ```
::: :::
### 移入展开 ### 选择即改变
在鼠标移入时就展开下级菜单,完成选择仍需要进行点击 点击或移入选项即表示选中该项,可用于选择任意一级菜单的选项
:::demo :::demo 若需要允许用户选择任意一级选项,则可将`change-on-select`赋值为`true`
```html ```html
<el-cascader <el-cascader
placeholder="请选择"
:options="options" :options="options"
expand-trigger="hover" change-on-select
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake', label: '一致'
}], }, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei', label: '侧向导航'
}], }, {
}], value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{ children: [{
value: 'zhonghuamen', value: 'table',
label: 'Zhong Hua Men', label: 'Table 表格'
}], }, {
}], value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}] }]
}; };
} }
...@@ -368,52 +1381,51 @@ ...@@ -368,52 +1381,51 @@
``` ```
::: :::
### 选择即改变 ### 动态加载次级选项
该模式下允许只选中父级选项。 当选中某一级时,动态加载该级下的选项。
:::demo :::demo 本例的选项数据源在初始化时不包含城市数据。利用`active-item-change`事件,可以在用户点击某个省份时拉取该省份下的城市数据。此外,本例还展示了`props`属性的用法。
```html ```html
<el-cascader <el-cascader
placeholder="请选择" :options="options2"
:options="options" @active-item-change="handleItemChange"
change-on-select :props="props"
></el-cascader> ></el-cascader>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options2: [{
value: 'zhejiang', label: '江苏',
label: 'Zhejiang', cities: []
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}, {
value: 'ningbo',
label: 'NingBo',
children: [{
value: 'jiangbei',
label: 'Jiang Bei',
}],
}],
}, { }, {
value: 'jiangsu', label: '浙江',
label: 'Jiangsu', cities: []
children: [{ }],
value: 'nanjing', props: {
label: 'Nanjing', value: 'label',
children: [{ children: 'cities'
value: 'zhonghuamen', }
label: 'Zhong Hua Men',
}],
}],
}]
}; };
},
methods: {
handleItemChange(val) {
console.log('active item:', val);
setTimeout(_ => {
if (val.indexOf('江苏') > -1 && !this.options2[0].cities.length) {
this.options2[0].cities = [{
label: '南京'
}];
} else if (val.indexOf('浙江') > -1 && !this.options2[1].cities.length) {
this.options2[1].cities = [{
label: '杭州'
}];
}
}, 300);
}
} }
}; };
</script> </script>
...@@ -422,48 +1434,226 @@ ...@@ -422,48 +1434,226 @@
### 可搜索 ### 可搜索
可以直接搜索选项并选择。 可以快捷地搜索选项并选择。
:::demo :::demo`filterable`赋值为`true`即可打开搜索功能。
```html ```html
<el-cascader <div class="block">
placeholder="请选择" <span class="demonstration">只可选择最后一级菜单的选项</span>
:options="options" <el-cascader
filterable placeholder="试试搜索:指南"
></el-cascader> :options="options"
filterable
></el-cascader>
</div>
<div class="block">
<span class="demonstration">可选择任意一级菜单的选项</span>
<el-cascader
placeholder="试试搜索:指南"
:options="options"
filterable
change-on-select
></el-cascader>
</div>
<script> <script>
module.exports = { export default {
data() { data() {
return { return {
options: [{ options: [{
value: 'zhejiang', value: 'zhinan',
label: 'Zhejiang', label: '指南',
children: [{ children: [{
value: 'hangzhou', value: 'shejiyuanze',
label: 'Hangzhou', label: '设计原则',
children: [{ children: [{
value: 'xihu', value: 'yizhi',
label: 'West Lake', label: '一致'
}], }, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, { }, {
value: 'ningbo', value: 'daohang',
label: 'NingBo', label: '导航',
children: [{ children: [{
value: 'jiangbei', value: 'cexiangdaohang',
label: 'Jiang Bei', label: '侧向导航'
}], }, {
}], value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, { }, {
value: 'jiangsu', value: 'zujian',
label: 'Jiangsu', label: '组件',
children: [{ children: [{
value: 'nanjing', value: 'basic',
label: 'Nanjing', label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{ children: [{
value: 'zhonghuamen', value: 'menu',
label: 'Zhong Hua Men', label: 'NavMenu 导航菜单'
}], }, {
}], value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}] }]
}; };
} }
...@@ -475,17 +1665,30 @@ ...@@ -475,17 +1665,30 @@
### Attributes ### Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | |---------- |-------- |---------- |------------- |-------- |
| options | 可选项数据源 | array | — | — | | options | 可选项数据源,键名可通过 `props` 属性配置 | array | — | — |
| value | 指定选中项 | array | — | — | | props | 配置选项,具体见下表 | object | — | — |
| popper-class | 自定义浮层类名 | string | — | — | | value | 选中项绑定值 | array | — | — |
| placeholder | 输入框占位文本 | string | — | — | | popper-class | 自定义浮层类名 | string | — | — |
| disabled | 是否禁用 | boolean | — | false | | placeholder | 输入框占位文本 | string | — | 请选择 |
| clearable | 是否支持清除 | boolean | — | false | | disabled | 是否禁用 | boolean | — | false |
| expand-trigger | 次级菜单的展开方式 | string | click / hover | 'click' | | clearable | 是否支持清空选项 | boolean | — | false |
| filterable | 是否支持搜索选项 | boolean | — | — | | expand-trigger | 次级菜单的展开方式 | string | click / hover | click |
| size | 尺寸 | string | large / small / mini | — | | show-all-levels | 输入框中是否显示选中值的完整路径 | boolean | — | true |
| filterable | 是否可搜索选项 | boolean | — | — |
| debounce | 搜索关键词输入的去抖延迟,毫秒 | number | — | 300 |
| change-on-select | 是否允许选择任意一级的选项 | boolean | — | false |
| size | 尺寸 | string | large / small / mini | — |
### props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------- | ----------------- | ------ | ------ | ------ |
| value | 指定选项的值为选项对象的某个属性值 | string | — | — |
| label | 指定选项标签为选项对象的某个属性值 | string | — | — |
| children | 指定选项的子选项为选项对象的某个属性值 | string | — | — |
| disabled | 指定选项的禁用为选项对象的某个属性值 | string | — | — |
### Events ### Events
| 事件名称 | 说明 | 回调参数 | | 事件名称 | 说明 | 回调参数 |
|---------- |-------- |---------- | |---------- |-------- |---------- |
| change | 当绑定值变化时触发的事件 | 当前值 | | change | 当绑定值变化时触发的事件 | 当前值 |
\ No newline at end of file | active-item-change | 当父级选项变化时触发的事件,仅在 `change-on-select``false` 时可用 | 各父级选项组成的数组 |
\ No newline at end of file
require('offline-plugin/runtime').install(); process.env.NODE_ENV === 'production' && require('offline-plugin/runtime').install();
import Vue from 'vue'; import Vue from 'vue';
import entry from './app'; import entry from './app';
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
}, },
{ {
"path": "/cascader", "path": "/cascader",
"title": "Cascader 级联选择" "title": "Cascader 级联选择"
}, },
{ {
"path": "/switch", "path": "/switch",
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
<el-input <el-input
ref="input" ref="input"
:readonly="!filterable" :readonly="!filterable"
:placeholder="displayValue ? undefined : placeholder" :placeholder="currentLabels.length ? undefined : placeholder"
v-model="inputValue" v-model="inputValue"
@change="handleInputChange" @change="debouncedInputChange"
:validate-event="false" :validate-event="false"
:size="size" :size="size"
:disabled="disabled" :disabled="disabled"
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<template slot="icon"> <template slot="icon">
<i <i
key="1" key="1"
v-if="inputHover && displayValue !== ''" v-if="clearable && inputHover && currentLabels.length"
class="el-input__icon el-icon-circle-close el-cascader__clearIcon" class="el-input__icon el-icon-circle-close el-cascader__clearIcon"
@click="clearValue" @click="clearValue"
></i> ></i>
...@@ -39,7 +39,17 @@ ...@@ -39,7 +39,17 @@
></i> ></i>
</template> </template>
</el-input> </el-input>
<span class="el-cascader__label" v-show="inputValue === ''">{{displayValue}}</span> <span class="el-cascader__label" v-show="inputValue === ''">
<template v-if="showAllLevels">
<template v-for="(label, index) in currentLabels">
{{ label }}
<span v-if="index < currentLabels.length - 1"> / </span>
</template>
</template>
<template v-else>
{{ currentLabels[currentLabels.length - 1] }}
</template>
</span>
</span> </span>
</template> </template>
...@@ -51,6 +61,8 @@ import Popper from 'element-ui/src/utils/vue-popper'; ...@@ -51,6 +61,8 @@ import Popper from 'element-ui/src/utils/vue-popper';
import Clickoutside from 'element-ui/src/utils/clickoutside'; import Clickoutside from 'element-ui/src/utils/clickoutside';
import emitter from 'element-ui/src/mixins/emitter'; import emitter from 'element-ui/src/mixins/emitter';
import Locale from 'element-ui/src/mixins/locale'; import Locale from 'element-ui/src/mixins/locale';
import { t } from 'element-ui/src/locale';
import debounce from 'throttle-debounce/debounce';
const popperMixin = { const popperMixin = {
props: { props: {
...@@ -84,17 +96,33 @@ export default { ...@@ -84,17 +96,33 @@ export default {
type: Array, type: Array,
required: true required: true
}, },
props: {
type: Object,
default() {
return {
children: 'children',
label: 'label',
value: 'value',
disabled: 'disabled'
};
}
},
value: { value: {
type: Array, type: Array,
default() { default() {
return []; return [];
} }
}, },
placeholder: String, placeholder: {
type: String,
default() {
return t('el.cascader.placeholder');
}
},
disabled: Boolean, disabled: Boolean,
clearable: { clearable: {
type: Boolean, type: Boolean,
default: true default: false
}, },
changeOnSelect: Boolean, changeOnSelect: Boolean,
popperClass: String, popperClass: String,
...@@ -103,20 +131,53 @@ export default { ...@@ -103,20 +131,53 @@ export default {
default: 'click' default: 'click'
}, },
filterable: Boolean, filterable: Boolean,
size: String size: String,
showAllLevels: {
type: Boolean,
default: true
},
debounce: {
type: Number,
default: 300
}
}, },
data() { data() {
return { return {
currentValue: this.value, currentValue: this.value,
displayValue: this.value.join('/'), menu: null,
debouncedInputChange() {},
menuVisible: false, menuVisible: false,
inputHover: false, inputHover: false,
inputValue: '', inputValue: '',
flatOptions: this.filterable && this.flattenOptions(this.options) flatOptions: null
}; };
}, },
computed: {
labelKey() {
return this.props.label || 'label';
},
valueKey() {
return this.props.value || 'value';
},
childrenKey() {
return this.props.children || 'children';
},
currentLabels() {
let options = this.options;
let labels = [];
this.currentValue.forEach(value => {
const targetOption = options && options.filter(option => option[this.valueKey] === value)[0];
if (targetOption) {
labels.push(targetOption[this.labelKey]);
options = targetOption[this.childrenKey];
}
});
return labels;
}
},
watch: { watch: {
menuVisible(value) { menuVisible(value) {
value ? this.showMenu() : this.hideMenu(); value ? this.showMenu() : this.hideMenu();
...@@ -125,29 +186,40 @@ export default { ...@@ -125,29 +186,40 @@ export default {
this.currentValue = value; this.currentValue = value;
}, },
currentValue(value) { currentValue(value) {
this.displayValue = value.join('/');
this.dispatch('ElFormItem', 'el.form.change', [value]); this.dispatch('ElFormItem', 'el.form.change', [value]);
}, },
options(value) { options: {
this.menu.options = value; deep: true,
handler(value) {
if (!this.menu) {
this.initMenu();
}
this.flatOptions = this.flattenOptions(this.options);
this.menu.options = value;
}
} }
}, },
methods: { methods: {
initMenu() {
this.menu = new Vue(ElCascaderMenu).$mount();
this.menu.options = this.options;
this.menu.props = this.props;
this.menu.expandTrigger = this.expandTrigger;
this.menu.changeOnSelect = this.changeOnSelect;
this.menu.popperClass = this.popperClass;
this.popperElm = this.menu.$el;
this.menu.$on('pick', this.handlePick);
this.menu.$on('activeItemChange', this.handleActiveItemChange);
},
showMenu() { showMenu() {
if (!this.menu) { if (!this.menu) {
this.menu = new Vue(ElCascaderMenu).$mount(); this.initMenu();
this.menu.options = this.options;
this.menu.expandTrigger = this.expandTrigger;
this.menu.changeOnSelect = this.changeOnSelect;
this.menu.popperClass = this.popperClass;
this.popperElm = this.menu.$el;
} }
this.menu.value = this.currentValue.slice(0); this.menu.value = this.currentValue.slice(0);
this.menu.visible = true; this.menu.visible = true;
this.menu.options = this.options; this.menu.options = this.options;
this.menu.$on('pick', this.handlePick);
this.updatePopper(); this.updatePopper();
this.$nextTick(_ => { this.$nextTick(_ => {
this.menu.inputWidth = this.$refs.input.$el.offsetWidth - 2; this.menu.inputWidth = this.$refs.input.$el.offsetWidth - 2;
...@@ -157,6 +229,12 @@ export default { ...@@ -157,6 +229,12 @@ export default {
this.inputValue = ''; this.inputValue = '';
this.menu.visible = false; this.menu.visible = false;
}, },
handleActiveItemChange(value) {
this.$nextTick(_ => {
this.updatePopper();
});
this.$emit('active-item-change', value);
},
handlePick(value, close = true) { handlePick(value, close = true) {
this.currentValue = value; this.currentValue = value;
this.$emit('input', value); this.$emit('input', value);
...@@ -176,14 +254,14 @@ export default { ...@@ -176,14 +254,14 @@ export default {
} }
let filteredFlatOptions = flatOptions.filter(optionsStack => { let filteredFlatOptions = flatOptions.filter(optionsStack => {
return optionsStack.some(option => option.label.indexOf(value) > -1); return optionsStack.some(option => new RegExp(value, 'i').test(option[this.labelKey]));
}); });
if (filteredFlatOptions.length > 0) { if (filteredFlatOptions.length > 0) {
filteredFlatOptions = filteredFlatOptions.map(optionStack => { filteredFlatOptions = filteredFlatOptions.map(optionStack => {
return { return {
__IS__FLAT__OPTIONS: true, __IS__FLAT__OPTIONS: true,
value: optionStack.map(item => item.value), value: optionStack.map(item => item[this.valueKey]),
label: this.renderFilteredOptionLabel(value, optionStack) label: this.renderFilteredOptionLabel(value, optionStack)
}; };
}); });
...@@ -198,8 +276,11 @@ export default { ...@@ -198,8 +276,11 @@ export default {
this.menu.options = filteredFlatOptions; this.menu.options = filteredFlatOptions;
}, },
renderFilteredOptionLabel(inputValue, optionsStack) { renderFilteredOptionLabel(inputValue, optionsStack) {
return optionsStack.map(({ label }, index) => { return optionsStack.map((option, index) => {
const node = label.indexOf(inputValue) > -1 ? this.highlightKeyword(label, inputValue) : label; const label = option[this.labelKey];
const keywordIndex = label.toLowerCase().indexOf(inputValue.toLowerCase());
const labelPart = label.slice(keywordIndex, inputValue.length + keywordIndex);
const node = keywordIndex > -1 ? this.highlightKeyword(label, labelPart) : label;
return index === 0 ? node : [' / ', node]; return index === 0 ? node : [' / ', node];
}); });
}, },
...@@ -215,10 +296,13 @@ export default { ...@@ -215,10 +296,13 @@ export default {
let flatOptions = []; let flatOptions = [];
options.forEach((option) => { options.forEach((option) => {
const optionsStack = ancestor.concat(option); const optionsStack = ancestor.concat(option);
if (!option.children) { if (!option[this.childrenKey]) {
flatOptions.push(optionsStack); flatOptions.push(optionsStack);
} else { } else {
flatOptions = flatOptions.concat(this.flattenOptions(option.children, optionsStack)); if (this.changeOnSelect) {
flatOptions.push(optionsStack);
}
flatOptions = flatOptions.concat(this.flattenOptions(option[this.childrenKey], optionsStack));
} }
}); });
return flatOptions; return flatOptions;
...@@ -238,6 +322,16 @@ export default { ...@@ -238,6 +322,16 @@ export default {
} }
this.menuVisible = !this.menuVisible; this.menuVisible = !this.menuVisible;
} }
},
created() {
this.debouncedInputChange = debounce(this.debounce, value => {
this.handleInputChange(value);
});
},
mounted() {
this.flatOptions = this.flattenOptions(this.options);
} }
}; };
</script> </script>
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
return { return {
inputWidth: 0, inputWidth: 0,
options: [], options: [],
props: {},
visible: false, visible: false,
activeValue: [], activeValue: [],
value: [], value: [],
...@@ -34,6 +35,20 @@ ...@@ -34,6 +35,20 @@
cache: false, cache: false,
get() { get() {
const activeValue = this.activeValue; const activeValue = this.activeValue;
const configurableProps = ['label', 'value', 'children', 'disabled'];
const formatOptions = options => {
options.forEach(option => {
if (option.__IS__FLAT__OPTIONS) return;
configurableProps.forEach(prop => {
const value = option[this.props[prop] || prop];
if (value) option[prop] = value;
});
if (Array.isArray(option.children)) {
formatOptions(option.children);
}
});
};
const loadActiveOptions = (options, activeOptions = []) => { const loadActiveOptions = (options, activeOptions = []) => {
const level = activeOptions.length; const level = activeOptions.length;
...@@ -48,6 +63,7 @@ ...@@ -48,6 +63,7 @@
return activeOptions; return activeOptions;
}; };
formatOptions(this.options);
return loadActiveOptions(this.options); return loadActiveOptions(this.options);
} }
} }
...@@ -66,7 +82,11 @@ ...@@ -66,7 +82,11 @@
const len = this.activeOptions.length; const len = this.activeOptions.length;
this.activeValue.splice(menuIndex, len, item.value); this.activeValue.splice(menuIndex, len, item.value);
this.activeOptions.splice(menuIndex + 1, len, item.children); this.activeOptions.splice(menuIndex + 1, len, item.children);
if (this.changeOnSelect) this.$emit('pick', this.activeValue, false); if (this.changeOnSelect) {
this.$emit('pick', this.activeValue, false);
} else {
this.$emit('activeItemChange', this.activeValue);
}
} }
}, },
...@@ -116,7 +136,7 @@ ...@@ -116,7 +136,7 @@
}); });
let menuStyle = {}; let menuStyle = {};
if (isFlat) { if (isFlat) {
menuStyle.width = this.inputWidth + 'px'; menuStyle.minWidth = this.inputWidth + 'px';
} }
return ( return (
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
.el-input__inner { .el-input__inner {
cursor: pointer; cursor: pointer;
background-color: transparent; background-color: transparent;
z-index: 1; z-index: var(--index-normal);
} }
.el-input__icon { .el-input__icon {
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
top: 0; top: 0;
height: 100%; height: 100%;
line-height: 34px; line-height: 34px;
padding: 0 15px 0 10px; padding: 0 25px 0 10px;
color: var(--input-color); color: var(--input-color);
width: 100%; width: 100%;
white-space: nowrap; white-space: nowrap;
...@@ -42,6 +42,11 @@ ...@@ -42,6 +42,11 @@
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
cursor: pointer; cursor: pointer;
font-size: 14px;
text-align: left;
span {
color: var(--color-light-silver);
}
} }
@m large { @m large {
...@@ -65,24 +70,23 @@ ...@@ -65,24 +70,23 @@
background: #fff; background: #fff;
position: absolute; position: absolute;
margin: 5px 0; margin: 5px 0;
z-index: 1001; z-index: calc(var(--index-normal) + 1);
border: var(--select-dropdown-border); border: var(--select-dropdown-border);
border-radius: var(--border-radius-small); border-radius: var(--border-radius-small);
overflow: hidden;
box-shadow: var(--select-dropdown-shadow); box-shadow: var(--select-dropdown-shadow);
} }
@b cascader-menu { @b cascader-menu {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
height: 180px; height: 204px;
overflow: auto; overflow: auto;
border-right: var(--select-dropdown-border); border-right: var(--select-dropdown-border);
background-color: var(--select-dropdown-background); background-color: var(--select-dropdown-background);
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
padding: 0; padding: 6px 0;
min-width: 110px; min-width: 160px;
&:last-child { &:last-child {
border-right: 0; border-right: 0;
...@@ -102,13 +106,13 @@ ...@@ -102,13 +106,13 @@
cursor: pointer; cursor: pointer;
@e keyword { @e keyword {
color: var(--color-danger); font-weight: bold;
} }
@m extensible { @m extensible {
&:after { &:after {
font-family: 'element-icons'; font-family: 'element-icons';
content: "\e602"; content: "\e606";
font-size: 12px; font-size: 12px;
transform: scale(0.8); transform: scale(0.8);
color: rgb(191, 203, 217); color: rgb(191, 203, 217);
...@@ -132,7 +136,7 @@ ...@@ -132,7 +136,7 @@
color: var(--color-white); color: var(--color-white);
background-color: var(--select-option-selected); background-color: var(--select-option-selected);
&.hover { &:hover {
background-color: var(--select-option-selected-hover); background-color: var(--select-option-selected-hover);
} }
} }
......
...@@ -12,7 +12,7 @@ export default { ...@@ -12,7 +12,7 @@ export default {
startTime: 'Hora de inicio', startTime: 'Hora de inicio',
endDate: 'Data de fim', endDate: 'Data de fim',
endTime: 'Hora de fim', endTime: 'Hora de fim',
year: 'Ano', year: '',
month1: 'Janeiro', month1: 'Janeiro',
month2: 'Fevereiro', month2: 'Fevereiro',
month3: 'Março', month3: 'Março',
......
...@@ -13,6 +13,7 @@ describe('Cascader', () => { ...@@ -13,6 +13,7 @@ describe('Cascader', () => {
ref="cascader" ref="cascader"
placeholder="请选择" placeholder="请选择"
:options="options" :options="options"
clearable
v-model="selectedOptions" v-model="selectedOptions"
></el-cascader> ></el-cascader>
`, `,
...@@ -456,6 +457,7 @@ describe('Cascader', () => { ...@@ -456,6 +457,7 @@ describe('Cascader', () => {
placeholder="请选择" placeholder="请选择"
:options="options" :options="options"
filterable filterable
:debounce="0"
v-model="selectedOptions" v-model="selectedOptions"
></el-cascader> ></el-cascader>
`, `,
...@@ -507,7 +509,7 @@ describe('Cascader', () => { ...@@ -507,7 +509,7 @@ describe('Cascader', () => {
const item1 = menuElm.querySelector('.el-cascader-menu__item'); const item1 = menuElm.querySelector('.el-cascader-menu__item');
expect(menuElm.children.length).to.be.equal(1); expect(menuElm.children.length).to.be.equal(1);
expect(menuElm.children[0].children.length).to.be.equal(1); expect(menuElm.children[0].children.length).to.be.equal(3);
done(); done();
item1.click(); item1.click();
...@@ -521,4 +523,106 @@ describe('Cascader', () => { ...@@ -521,4 +523,106 @@ describe('Cascader', () => {
}, 500); }, 500);
}, 300); }, 300);
}); });
it('props', done => {
vm = createVue({
template: `
<el-cascader
ref="cascader"
:options="options"
:props="props"
v-model="selectedOptions"
></el-cascader>
`,
data() {
return {
options: [{
label: 'Zhejiang',
cities: [{
label: 'Hangzhou'
}, {
label: 'NingBo'
}]
}, {
label: 'Jiangsu',
cities: [{
label: 'Nanjing'
}]
}],
props: {
value: 'label',
children: 'cities'
},
selectedOptions: []
};
}
}, true);
vm.$el.click();
setTimeout(_ => {
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
const menu = vm.$refs.cascader.menu;
const menuElm = menu.$el;
let items = menuElm.querySelectorAll('.el-cascader-menu__item');
expect(items.length).to.equal(2);
items[0].click();
setTimeout(_ => {
items = menuElm.querySelectorAll('.el-cascader-menu__item');
expect(items.length).to.equal(4);
expect(items[items.length - 1].innerText).to.equal('NingBo');
done();
}, 100);
}, 100);
});
it('show last level', done => {
vm = createVue({
template: `
<el-cascader
ref="cascader"
:options="options"
:show-all-levels="false"
v-model="selectedOptions"
></el-cascader>
`,
data() {
return {
options: [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake'
}]
}, {
value: 'ningbo',
label: 'NingBo',
children: [{
value: 'jiangbei',
label: 'Jiang Bei'
}]
}]
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men'
}]
}]
}],
selectedOptions: ['zhejiang', 'ningbo', 'jiangbei']
};
}
}, true);
setTimeout(_ => {
const span = vm.$el.querySelector('.el-cascader__label');
expect(span.innerText).to.equal('Jiang Bei');
done();
}, 100);
});
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment