mirror of https://github.com/ElemeFE/element
commit
c672727673
|
@ -58,5 +58,6 @@
|
||||||
"scrollbar": "./packages/scrollbar/index.js",
|
"scrollbar": "./packages/scrollbar/index.js",
|
||||||
"carousel-item": "./packages/carousel-item/index.js",
|
"carousel-item": "./packages/carousel-item/index.js",
|
||||||
"collapse": "./packages/collapse/index.js",
|
"collapse": "./packages/collapse/index.js",
|
||||||
"collapse-item": "./packages/collapse-item/index.js"
|
"collapse-item": "./packages/collapse-item/index.js",
|
||||||
|
"cascader": "./packages/cascader/index.js"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,487 @@
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
optionsWithDisabled: [{
|
||||||
|
value: 'zhejiang',
|
||||||
|
label: 'Zhejiang',
|
||||||
|
disabled: true,
|
||||||
|
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: [],
|
||||||
|
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen']
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(value) {
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.demo-cascader {
|
||||||
|
.el-cascader {
|
||||||
|
width: 222px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demo-cascader-size {
|
||||||
|
.el-cascader {
|
||||||
|
vertical-align: top;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
## Cascader
|
||||||
|
|
||||||
|
It's used to select from a set of associated data set. Such as province/city/district, company level, and categories.
|
||||||
|
|
||||||
|
### Basic usage
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="options"
|
||||||
|
v-model="selectedOptions"
|
||||||
|
@change="handleChange"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(value) {
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Disabled option
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="optionsWithDisabled"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
optionsWithDisabled: [{
|
||||||
|
value: 'zhejiang',
|
||||||
|
label: 'Zhejiang',
|
||||||
|
disabled: true,
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Default Value
|
||||||
|
|
||||||
|
:::demo default value is assigned by an array type value.
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="options"
|
||||||
|
v-model="selectedOptions2"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Size
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<div class="demo-cascader-size">
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="options"
|
||||||
|
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>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Hover to expand
|
||||||
|
|
||||||
|
Hover to expand the next level options, click to select option.
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="options"
|
||||||
|
expand-trigger="hover"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Change on select
|
||||||
|
|
||||||
|
Allow only select parent options.
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="options"
|
||||||
|
change-on-select
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Search
|
||||||
|
|
||||||
|
Search and select options directly.
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="Please select"
|
||||||
|
:options="options"
|
||||||
|
filterable
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Attributes
|
||||||
|
| Attribute | Description | Type | Options | Default|
|
||||||
|
|---------- |-------------------- |---------|------------- |-------- |
|
||||||
|
| options | data source of the options | array | — | — |
|
||||||
|
| value | selected value | array | — | — |
|
||||||
|
| popper-class | className of popup overlay | string | — | — |
|
||||||
|
| placeholder | input placeholder | string | — | — |
|
||||||
|
| disabled | 是否禁用 | boolean | — | false |
|
||||||
|
| clearable | whether allow clear | boolean | — | false |
|
||||||
|
| expand-trigger | trigger mode of expandind the current item | string | click / hover | 'click' |
|
||||||
|
| filterable | whether the options can be searched | boolean | — | — |
|
||||||
|
| size | size | string | large / small / mini | — |
|
||||||
|
|
||||||
|
### Events
|
||||||
|
| Event Name | Description | Parameters |
|
||||||
|
|---------- |-------- |---------- |
|
||||||
|
| change | triggers when the binding value changes | value |
|
|
@ -0,0 +1,491 @@
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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'
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
optionsWithDisabled: [{
|
||||||
|
value: 'zhejiang',
|
||||||
|
label: 'Zhejiang',
|
||||||
|
disabled: true,
|
||||||
|
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: [],
|
||||||
|
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen']
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(value) {
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.demo-cascader {
|
||||||
|
.el-cascader {
|
||||||
|
width: 222px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demo-cascader-size {
|
||||||
|
.el-cascader {
|
||||||
|
vertical-align: top;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
## 级联选择
|
||||||
|
|
||||||
|
需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。
|
||||||
|
|
||||||
|
从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。
|
||||||
|
|
||||||
|
### 基本使用
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
v-model="selectedOptions"
|
||||||
|
@change="handleChange"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(value) {
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 禁用选项
|
||||||
|
|
||||||
|
通过在数据源中设置 `disabled` 字段来声明该选项时禁用的
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="optionsWithDisabled"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
optionsWithDisabled: [{
|
||||||
|
value: 'zhejiang',
|
||||||
|
label: 'Zhejiang',
|
||||||
|
disabled: true,
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 默认值
|
||||||
|
|
||||||
|
:::demo 默认值通过数组的方式指定。
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
v-model="selectedOptions2"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
selectedOptions2: ['jiangsu', 'nanjing', 'zhonghuamen']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 尺寸
|
||||||
|
|
||||||
|
:::demo 提供三种尺寸的级联选择器
|
||||||
|
```html
|
||||||
|
<div class="demo-cascader-size">
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
size="large"
|
||||||
|
></el-cascader>
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
></el-cascader>
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
size="small"
|
||||||
|
></el-cascader>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 移入展开
|
||||||
|
|
||||||
|
在鼠标移入时就展开下级菜单,完成选择仍需要进行点击。
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
expand-trigger="hover"
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 选择即改变
|
||||||
|
|
||||||
|
该模式下允许只选中父级选项。
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
change-on-select
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 可搜索
|
||||||
|
|
||||||
|
可以直接搜索选项并选择。
|
||||||
|
|
||||||
|
:::demo
|
||||||
|
```html
|
||||||
|
<el-cascader
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
filterable
|
||||||
|
></el-cascader>
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
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',
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Attributes
|
||||||
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||||
|
|---------- |-------- |---------- |------------- |-------- |
|
||||||
|
| options | 可选项数据源 | array | — | — |
|
||||||
|
| value | 指定选中项 | array | — | — |
|
||||||
|
| popper-class | 自定义浮层类名 | string | — | — |
|
||||||
|
| placeholder | 输入框占位文本 | string | — | — |
|
||||||
|
| disabled | 是否禁用 | boolean | — | false |
|
||||||
|
| clearable | 是否支持清除 | boolean | — | false |
|
||||||
|
| expand-trigger | 次级菜单的展开方式 | string | click / hover | 'click' |
|
||||||
|
| filterable | 是否支持搜索选项 | boolean | — | — |
|
||||||
|
| size | 尺寸 | string | large / small / mini | — |
|
||||||
|
|
||||||
|
### Events
|
||||||
|
| 事件名称 | 说明 | 回调参数 |
|
||||||
|
|---------- |-------- |---------- |
|
||||||
|
| change | 当绑定值变化时触发的事件 | 当前值 |
|
|
@ -76,6 +76,10 @@
|
||||||
"path": "/select",
|
"path": "/select",
|
||||||
"title": "Select 选择器"
|
"title": "Select 选择器"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "/cascader",
|
||||||
|
"title": "Cascader 级联选择"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "/switch",
|
"path": "/switch",
|
||||||
"title": "Switch 开关"
|
"title": "Switch 开关"
|
||||||
|
@ -298,6 +302,10 @@
|
||||||
"path": "/select",
|
"path": "/select",
|
||||||
"title": "Select"
|
"title": "Select"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "/cascader",
|
||||||
|
"title": "Cascader"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "/switch",
|
"path": "/switch",
|
||||||
"title": "Switch"
|
"title": "Switch"
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
var cooking = require('cooking');
|
||||||
|
var path = require('path');
|
||||||
|
var config = require('../../build/config');
|
||||||
|
|
||||||
|
cooking.set({
|
||||||
|
entry: {
|
||||||
|
index: path.join(__dirname, 'index.js')
|
||||||
|
},
|
||||||
|
dist: path.join(__dirname, 'lib'),
|
||||||
|
template: false,
|
||||||
|
format: 'umd',
|
||||||
|
moduleName: 'ElCascader',
|
||||||
|
extends: ['vue2'],
|
||||||
|
alias: config.alias,
|
||||||
|
externals: { vue: config.vue }
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = cooking.resolve();
|
|
@ -0,0 +1,8 @@
|
||||||
|
import Cascader from './src/main';
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
Cascader.install = function(Vue) {
|
||||||
|
Vue.component(Cascader.name, Cascader);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Cascader;
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "element-cascader",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "A cascader component for Vue.js.",
|
||||||
|
"keywords": [
|
||||||
|
"element",
|
||||||
|
"vue",
|
||||||
|
"component"
|
||||||
|
],
|
||||||
|
"main": "./lib/index.js",
|
||||||
|
"repository": "https://github.com/ElemeFE/element/tree/master/packages/cascader",
|
||||||
|
"author": "elemefe",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
<template>
|
||||||
|
<span
|
||||||
|
class="el-cascader"
|
||||||
|
:class="[
|
||||||
|
{
|
||||||
|
'is-opened': menuVisible,
|
||||||
|
'is-disabled': disabled
|
||||||
|
},
|
||||||
|
size ? 'el-cascader--' + size : ''
|
||||||
|
]"
|
||||||
|
@click="handleClick"
|
||||||
|
@mouseenter="inputHover = true"
|
||||||
|
@mouseleave="inputHover = false"
|
||||||
|
ref="reference"
|
||||||
|
v-clickoutside="handleClickoutside"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
ref="input"
|
||||||
|
:readonly="!filterable"
|
||||||
|
:placeholder="displayValue ? undefined : placeholder"
|
||||||
|
v-model="inputValue"
|
||||||
|
@change="handleInputChange"
|
||||||
|
:validate-event="false"
|
||||||
|
:size="size"
|
||||||
|
:disabled="disabled"
|
||||||
|
>
|
||||||
|
<template slot="icon">
|
||||||
|
<i
|
||||||
|
key="1"
|
||||||
|
v-if="inputHover && displayValue !== ''"
|
||||||
|
class="el-input__icon el-icon-circle-close el-cascader__clearIcon"
|
||||||
|
@click="clearValue"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
key="2"
|
||||||
|
v-else
|
||||||
|
class="el-input__icon el-icon-caret-bottom"
|
||||||
|
:class="{ 'is-reverse': menuVisible }"
|
||||||
|
></i>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<span class="el-cascader__label" v-show="inputValue === ''">{{displayValue}}</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
import ElCascaderMenu from './menu';
|
||||||
|
import ElInput from 'element-ui/packages/input';
|
||||||
|
import Popper from 'element-ui/src/utils/vue-popper';
|
||||||
|
import Clickoutside from 'element-ui/src/utils/clickoutside';
|
||||||
|
import emitter from 'element-ui/src/mixins/emitter';
|
||||||
|
import Locale from 'element-ui/src/mixins/locale';
|
||||||
|
|
||||||
|
const popperMixin = {
|
||||||
|
props: {
|
||||||
|
placement: {
|
||||||
|
type: String,
|
||||||
|
default: 'bottom-start'
|
||||||
|
},
|
||||||
|
appendToBody: Popper.props.appendToBody,
|
||||||
|
offset: Popper.props.offset,
|
||||||
|
boundariesPadding: Popper.props.boundariesPadding,
|
||||||
|
popperOptions: Popper.props.popperOptions
|
||||||
|
},
|
||||||
|
methods: Popper.methods,
|
||||||
|
data: Popper.data,
|
||||||
|
beforeDestroy: Popper.beforeDestroy
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ElCascader',
|
||||||
|
|
||||||
|
directives: { Clickoutside },
|
||||||
|
|
||||||
|
mixins: [popperMixin, emitter, Locale],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
ElInput
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
placeholder: String,
|
||||||
|
disabled: Boolean,
|
||||||
|
clearable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
changeOnSelect: Boolean,
|
||||||
|
popperClass: String,
|
||||||
|
expandTrigger: {
|
||||||
|
type: String,
|
||||||
|
default: 'click'
|
||||||
|
},
|
||||||
|
filterable: Boolean,
|
||||||
|
size: String
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentValue: this.value,
|
||||||
|
displayValue: this.value.join('/'),
|
||||||
|
menuVisible: false,
|
||||||
|
inputHover: false,
|
||||||
|
inputValue: '',
|
||||||
|
flatOptions: this.filterable && this.flattenOptions(this.options)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
menuVisible(value) {
|
||||||
|
value ? this.showMenu() : this.hideMenu();
|
||||||
|
},
|
||||||
|
value(value) {
|
||||||
|
this.currentValue = value;
|
||||||
|
},
|
||||||
|
currentValue(value) {
|
||||||
|
this.displayValue = value.join('/');
|
||||||
|
this.dispatch('ElFormItem', 'el.form.change', [value]);
|
||||||
|
},
|
||||||
|
options(value) {
|
||||||
|
this.menu.options = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
showMenu() {
|
||||||
|
if (!this.menu) {
|
||||||
|
this.menu = new Vue(ElCascaderMenu).$mount();
|
||||||
|
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.visible = true;
|
||||||
|
this.menu.options = this.options;
|
||||||
|
this.menu.$on('pick', this.handlePick);
|
||||||
|
this.updatePopper();
|
||||||
|
this.$nextTick(_ => {
|
||||||
|
this.menu.inputWidth = this.$refs.input.$el.offsetWidth - 2;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hideMenu() {
|
||||||
|
this.inputValue = '';
|
||||||
|
this.menu.visible = false;
|
||||||
|
},
|
||||||
|
handlePick(value, close = true) {
|
||||||
|
this.currentValue = value;
|
||||||
|
this.$emit('input', value);
|
||||||
|
this.$emit('change', value);
|
||||||
|
|
||||||
|
if (close) {
|
||||||
|
this.menuVisible = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleInputChange(value) {
|
||||||
|
if (!this.menuVisible) return;
|
||||||
|
const flatOptions = this.flatOptions;
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
this.menu.options = this.options;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let filteredFlatOptions = flatOptions.filter(optionsStack => {
|
||||||
|
return optionsStack.some(option => option.label.indexOf(value) > -1);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filteredFlatOptions.length > 0) {
|
||||||
|
filteredFlatOptions = filteredFlatOptions.map(optionStack => {
|
||||||
|
return {
|
||||||
|
__IS__FLAT__OPTIONS: true,
|
||||||
|
value: optionStack.map(item => item.value),
|
||||||
|
label: this.renderFilteredOptionLabel(value, optionStack)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
filteredFlatOptions = [{
|
||||||
|
__IS__FLAT__OPTIONS: true,
|
||||||
|
label: this.t('el.cascader.noMatch'),
|
||||||
|
value: '',
|
||||||
|
disabled: true
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
this.menu.options = filteredFlatOptions;
|
||||||
|
},
|
||||||
|
renderFilteredOptionLabel(inputValue, optionsStack) {
|
||||||
|
return optionsStack.map(({ label }, index) => {
|
||||||
|
const node = label.indexOf(inputValue) > -1 ? this.highlightKeyword(label, inputValue) : label;
|
||||||
|
return index === 0 ? node : [' / ', node];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
highlightKeyword(label, keyword) {
|
||||||
|
const h = this._c;
|
||||||
|
return label.split(keyword)
|
||||||
|
.map((node, index) => index === 0 ? node : [
|
||||||
|
h('span', { class: { 'el-cascader-menu__item__keyword': true }}, [this._v(keyword)]),
|
||||||
|
node
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
flattenOptions(options, ancestor = []) {
|
||||||
|
let flatOptions = [];
|
||||||
|
options.forEach((option) => {
|
||||||
|
const optionsStack = ancestor.concat(option);
|
||||||
|
if (!option.children) {
|
||||||
|
flatOptions.push(optionsStack);
|
||||||
|
} else {
|
||||||
|
flatOptions = flatOptions.concat(this.flattenOptions(option.children, optionsStack));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return flatOptions;
|
||||||
|
},
|
||||||
|
clearValue(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this.handlePick([], true);
|
||||||
|
},
|
||||||
|
handleClickoutside() {
|
||||||
|
this.menuVisible = false;
|
||||||
|
},
|
||||||
|
handleClick() {
|
||||||
|
if (this.disabled) return;
|
||||||
|
if (this.filterable) {
|
||||||
|
this.menuVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.menuVisible = !this.menuVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,148 @@
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ElCascaderMenu',
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inputWidth: 0,
|
||||||
|
options: [],
|
||||||
|
visible: false,
|
||||||
|
activeValue: [],
|
||||||
|
value: [],
|
||||||
|
expandTrigger: 'click',
|
||||||
|
changeOnSelect: false,
|
||||||
|
popperClass: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
visible(value) {
|
||||||
|
if (value) {
|
||||||
|
this.activeValue = this.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
immediate: true,
|
||||||
|
handler(value) {
|
||||||
|
this.activeValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
activeOptions: {
|
||||||
|
cache: false,
|
||||||
|
get() {
|
||||||
|
const activeValue = this.activeValue;
|
||||||
|
|
||||||
|
const loadActiveOptions = (options, activeOptions = []) => {
|
||||||
|
const level = activeOptions.length;
|
||||||
|
activeOptions[level] = options;
|
||||||
|
let active = activeValue[level];
|
||||||
|
if (active) {
|
||||||
|
options = options.filter(option => option.value === active)[0];
|
||||||
|
if (options && options.children) {
|
||||||
|
loadActiveOptions(options.children, activeOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activeOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
return loadActiveOptions(this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
select(item, menuIndex) {
|
||||||
|
if (item.__IS__FLAT__OPTIONS) {
|
||||||
|
this.activeValue = item.value;
|
||||||
|
} else {
|
||||||
|
this.activeValue.splice(menuIndex, 1, item.value);
|
||||||
|
}
|
||||||
|
this.$emit('pick', this.activeValue);
|
||||||
|
},
|
||||||
|
activeItem(item, menuIndex) {
|
||||||
|
const len = this.activeOptions.length;
|
||||||
|
this.activeValue.splice(menuIndex, len, item.value);
|
||||||
|
this.activeOptions.splice(menuIndex + 1, len, item.children);
|
||||||
|
if (this.changeOnSelect) this.$emit('pick', this.activeValue, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render(h) {
|
||||||
|
const {
|
||||||
|
activeValue,
|
||||||
|
activeOptions,
|
||||||
|
visible,
|
||||||
|
expandTrigger,
|
||||||
|
popperClass
|
||||||
|
} = this;
|
||||||
|
|
||||||
|
const menus = this._l(activeOptions, (menu, menuIndex) => {
|
||||||
|
let isFlat = false;
|
||||||
|
const items = this._l(menu, item => {
|
||||||
|
const events = {
|
||||||
|
on: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item.__IS__FLAT__OPTIONS) isFlat = true;
|
||||||
|
|
||||||
|
if (!item.disabled) {
|
||||||
|
if (item.children) {
|
||||||
|
let triggerEvent = {
|
||||||
|
click: 'click',
|
||||||
|
hover: 'mouseenter'
|
||||||
|
}[expandTrigger];
|
||||||
|
events.on[triggerEvent] = () => { this.activeItem(item, menuIndex); };
|
||||||
|
} else {
|
||||||
|
events.on.click = () => { this.select(item, menuIndex); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
class={{
|
||||||
|
'el-cascader-menu__item': true,
|
||||||
|
'el-cascader-menu__item--extensible': item.children,
|
||||||
|
'is-active': item.value === activeValue[menuIndex],
|
||||||
|
'is-disabled': item.disabled
|
||||||
|
}}
|
||||||
|
{...events}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
let menuStyle = {};
|
||||||
|
if (isFlat) {
|
||||||
|
menuStyle.width = this.inputWidth + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul
|
||||||
|
class={{
|
||||||
|
'el-cascader-menu': true,
|
||||||
|
'el-cascader-menu--flexible': isFlat
|
||||||
|
}}
|
||||||
|
style={menuStyle}>
|
||||||
|
{items}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<transition name="el-zoom-in-top">
|
||||||
|
<div
|
||||||
|
v-show={visible}
|
||||||
|
class={[
|
||||||
|
'el-cascader-menus',
|
||||||
|
popperClass
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{menus}
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,44 +1,163 @@
|
||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
@import "./input.css";
|
@import "./input.css";
|
||||||
@import "./common/var.css";
|
@import "./common/var.css";
|
||||||
/*@import "./core/dropdown.css";*/
|
|
||||||
|
|
||||||
@component-namespace element {
|
@component-namespace el {
|
||||||
|
|
||||||
@b cascader {
|
@b cascader {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
@e dropdown {
|
.el-input,
|
||||||
background-color: var(--cascader-menu-fill);
|
.el-input__inner {
|
||||||
border: var(--cascader-menu-border);
|
cursor: pointer;
|
||||||
border-radius: var(--cascader-menu-radius);
|
background-color: transparent;
|
||||||
box-shadow: var(--cascader-menu-submenu-shadow);
|
z-index: 1;
|
||||||
margin-top: 5px;
|
}
|
||||||
max-height: var(--cascader-height);
|
|
||||||
|
.el-input__icon {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon-caret-bottom {
|
||||||
|
transition: transform .3s;
|
||||||
|
|
||||||
|
@when reverse {
|
||||||
|
transform: rotateZ(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@e label {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 34px;
|
||||||
|
padding: 0 15px 0 10px;
|
||||||
|
color: var(--input-color);
|
||||||
|
width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
z-index: 10;
|
text-overflow: ellipsis;
|
||||||
}
|
|
||||||
|
|
||||||
@e wrap {
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@e menu {
|
@m large {
|
||||||
border: 0;
|
font-size: var(--input-large-font-size);
|
||||||
box-shadow: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
position: relative;
|
|
||||||
vertical-align: top;
|
|
||||||
|
|
||||||
&::before {
|
.el-cascader__label {
|
||||||
border-left: var(--cascader-menu-border);
|
line-height: calc(var(--input-large-height) - 2);
|
||||||
content: " ";
|
}
|
||||||
height: var(--cascader-height);
|
}
|
||||||
left: 0;
|
@m small {
|
||||||
position: absolute;
|
font-size: var(--input-small-font-size);
|
||||||
|
|
||||||
|
.el-cascader__label {
|
||||||
|
line-height: calc(var(--input-small-height) - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@b cascader-menus {
|
||||||
|
white-space: nowrap;
|
||||||
|
background: #fff;
|
||||||
|
position: absolute;
|
||||||
|
margin: 5px 0;
|
||||||
|
z-index: 1001;
|
||||||
|
border: var(--select-dropdown-border);
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: var(--select-dropdown-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@b cascader-menu {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
height: 180px;
|
||||||
|
overflow: auto;
|
||||||
|
border-right: var(--select-dropdown-border);
|
||||||
|
background-color: var(--select-dropdown-background);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
min-width: 110px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@e item {
|
||||||
|
font-size: var(--select-font-size);
|
||||||
|
padding: 8px 30px 8px 10px;
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: var(--select-option-color);
|
||||||
|
height: var(--select-option-height);
|
||||||
|
line-height: 1.5;
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@e keyword {
|
||||||
|
color: var(--color-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@m extensible {
|
||||||
|
&:after {
|
||||||
|
font-family: 'element-icons';
|
||||||
|
content: "\e602";
|
||||||
|
font-size: 12px;
|
||||||
|
transform: scale(0.8);
|
||||||
|
color: rgb(191, 203, 217);
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@when disabled {
|
||||||
|
color: var(--select-option-disabled-color);
|
||||||
|
background-color: var(--select-option-disabled-background);
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@when active {
|
||||||
|
color: var(--color-white);
|
||||||
|
background-color: var(--select-option-selected);
|
||||||
|
|
||||||
|
&.hover {
|
||||||
|
background-color: var(--select-option-selected-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--select-option-hover-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
color: var(--color-white);
|
||||||
|
background-color: var(--select-option-selected);
|
||||||
|
|
||||||
|
&.hover {
|
||||||
|
background-color: var(--select-option-selected-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@m flexible {
|
||||||
|
height: auto;
|
||||||
|
max-height: 180px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.el-cascader-menu__item {
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,7 @@
|
||||||
|
|
||||||
--select-option-color: var(--link-color);
|
--select-option-color: var(--link-color);
|
||||||
--select-option-disabled-color: var(--color-extra-light-silver);
|
--select-option-disabled-color: var(--color-extra-light-silver);
|
||||||
|
--select-option-disabled-background: var(--color-white);
|
||||||
--select-option-height: 36px;
|
--select-option-height: 36px;
|
||||||
--select-option-hover-background: var(--color-light-gray);
|
--select-option-hover-background: var(--color-light-gray);
|
||||||
--select-option-selected: var(--color-primary);
|
--select-option-selected: var(--color-primary);
|
||||||
|
|
|
@ -44,3 +44,4 @@
|
||||||
@import "./carousel.css";
|
@import "./carousel.css";
|
||||||
@import "./carousel-item.css";
|
@import "./carousel-item.css";
|
||||||
@import "./collapse.css";
|
@import "./collapse.css";
|
||||||
|
@import "./cascader.css";
|
||||||
|
|
|
@ -60,6 +60,7 @@ import Scrollbar from '../packages/scrollbar';
|
||||||
import CarouselItem from '../packages/carousel-item';
|
import CarouselItem from '../packages/carousel-item';
|
||||||
import Collapse from '../packages/collapse';
|
import Collapse from '../packages/collapse';
|
||||||
import CollapseItem from '../packages/collapse-item';
|
import CollapseItem from '../packages/collapse-item';
|
||||||
|
import Cascader from '../packages/cascader';
|
||||||
import locale from 'element-ui/src/locale';
|
import locale from 'element-ui/src/locale';
|
||||||
|
|
||||||
const components = [
|
const components = [
|
||||||
|
@ -118,7 +119,8 @@ const components = [
|
||||||
Scrollbar,
|
Scrollbar,
|
||||||
CarouselItem,
|
CarouselItem,
|
||||||
Collapse,
|
Collapse,
|
||||||
CollapseItem
|
CollapseItem,
|
||||||
|
Cascader
|
||||||
];
|
];
|
||||||
|
|
||||||
const install = function(Vue, opts = {}) {
|
const install = function(Vue, opts = {}) {
|
||||||
|
@ -211,5 +213,6 @@ module.exports = {
|
||||||
Scrollbar,
|
Scrollbar,
|
||||||
CarouselItem,
|
CarouselItem,
|
||||||
Collapse,
|
Collapse,
|
||||||
CollapseItem
|
CollapseItem,
|
||||||
|
Cascader
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,6 +56,10 @@ export default {
|
||||||
noData: 'No data',
|
noData: 'No data',
|
||||||
placeholder: 'Select'
|
placeholder: 'Select'
|
||||||
},
|
},
|
||||||
|
cascader: {
|
||||||
|
noMatch: 'No matching data',
|
||||||
|
placeholder: 'Select'
|
||||||
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
goto: 'Go to',
|
goto: 'Go to',
|
||||||
pagesize: '/page',
|
pagesize: '/page',
|
||||||
|
|
|
@ -56,6 +56,10 @@ export default {
|
||||||
noData: '无数据',
|
noData: '无数据',
|
||||||
placeholder: '请选择'
|
placeholder: '请选择'
|
||||||
},
|
},
|
||||||
|
cascader: {
|
||||||
|
noMatch: '无匹配数据',
|
||||||
|
placeholder: '请选择'
|
||||||
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
goto: '前往',
|
goto: '前往',
|
||||||
pagesize: '条/页',
|
pagesize: '条/页',
|
||||||
|
|
|
@ -83,6 +83,7 @@ export default {
|
||||||
this.$slots.reference[0]) {
|
this.$slots.reference[0]) {
|
||||||
reference = this.referenceElm = this.$slots.reference[0].elm;
|
reference = this.referenceElm = this.$slots.reference[0].elm;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!popper || !reference) return;
|
if (!popper || !reference) return;
|
||||||
if (this.visibleArrow) this.appendArrow(popper);
|
if (this.visibleArrow) this.appendArrow(popper);
|
||||||
if (this.appendToBody) document.body.appendChild(this.popperElm);
|
if (this.appendToBody) document.body.appendChild(this.popperElm);
|
||||||
|
|
|
@ -0,0 +1,524 @@
|
||||||
|
import { createVue, destroyVM, triggerEvent } from '../util';
|
||||||
|
|
||||||
|
describe('Cascader', () => {
|
||||||
|
let vm;
|
||||||
|
afterEach(() => {
|
||||||
|
destroyVM(vm);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('create', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
vm.$el.click();
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
|
||||||
|
|
||||||
|
const menu = vm.$refs.cascader.menu;
|
||||||
|
const menuElm = menu.$el;
|
||||||
|
const item1 = menuElm.querySelector('.el-cascader-menu__item');
|
||||||
|
|
||||||
|
item1.click();
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(2);
|
||||||
|
expect(item1.classList.contains('is-active')).to.be.true;
|
||||||
|
|
||||||
|
const item2 = menuElm.children[1].querySelector('.el-cascader-menu__item');
|
||||||
|
item2.click();
|
||||||
|
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(3);
|
||||||
|
expect(item2.classList.contains('is-active')).to.be.true;
|
||||||
|
|
||||||
|
const item3 = menuElm.children[2].querySelector('.el-cascader-menu__item');
|
||||||
|
item3.click();
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
|
||||||
|
expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
|
||||||
|
expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
|
||||||
|
expect(vm.selectedOptions[2]).to.be.equal('xihu');
|
||||||
|
|
||||||
|
triggerEvent(vm.$refs.cascader.$el, 'mouseenter');
|
||||||
|
vm.$nextTick(_ => {
|
||||||
|
vm.$refs.cascader.$el.querySelector('.el-cascader__clearIcon').click();
|
||||||
|
vm.$nextTick(_ => {
|
||||||
|
expect(vm.selectedOptions.length).to.be.equal(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
it('not allow clearable', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
:clearable="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: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
triggerEvent(vm.$refs.cascader.$el, 'mouseenter');
|
||||||
|
vm.$nextTick(_ => {
|
||||||
|
expect(vm.$refs.cascader.$el.querySelector('.el-cascader__clearIcon')).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('disabled options', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
v-model="selectedOptions"
|
||||||
|
></el-cascader>
|
||||||
|
`,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options: [{
|
||||||
|
value: 'zhejiang',
|
||||||
|
label: 'Zhejiang',
|
||||||
|
disabled: true,
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
vm.$el.click();
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
|
||||||
|
|
||||||
|
const menu = vm.$refs.cascader.menu;
|
||||||
|
const menuElm = menu.$el;
|
||||||
|
const item1 = menuElm.querySelector('.el-cascader-menu__item');
|
||||||
|
|
||||||
|
item1.click();
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(1);
|
||||||
|
expect(item1.classList.contains('is-active')).to.be.false;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
it('default value', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
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', 'hangzhou', 'xihu']
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
vm.$el.click();
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
|
||||||
|
|
||||||
|
const menu = vm.$refs.cascader.menu;
|
||||||
|
const menuElm = menu.$el;
|
||||||
|
const item1 = menuElm.children[0].querySelector('.el-cascader-menu__item');
|
||||||
|
const item2 = menuElm.children[1].querySelector('.el-cascader-menu__item');
|
||||||
|
const item3 = menuElm.children[2].querySelector('.el-cascader-menu__item');
|
||||||
|
|
||||||
|
expect(menuElm.children.length).to.be.equal(3);
|
||||||
|
expect(item1.classList.contains('is-active')).to.be.true;
|
||||||
|
expect(item2.classList.contains('is-active')).to.be.true;
|
||||||
|
expect(item3.classList.contains('is-active')).to.be.true;
|
||||||
|
|
||||||
|
document.body.click();
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
|
||||||
|
done();
|
||||||
|
}, 500);
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
it('expand by hover', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
expand-trigger="hover"
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
vm.$el.click();
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
|
||||||
|
|
||||||
|
const menu = vm.$refs.cascader.menu;
|
||||||
|
const menuElm = menu.$el;
|
||||||
|
const item1 = menuElm.querySelector('.el-cascader-menu__item');
|
||||||
|
|
||||||
|
triggerEvent(item1, 'mouseenter');
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(2);
|
||||||
|
expect(item1.classList.contains('is-active')).to.be.true;
|
||||||
|
|
||||||
|
const item2 = menuElm.children[1].querySelector('.el-cascader-menu__item');
|
||||||
|
triggerEvent(item2, 'mouseenter');
|
||||||
|
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(3);
|
||||||
|
expect(item2.classList.contains('is-active')).to.be.true;
|
||||||
|
|
||||||
|
const item3 = menuElm.children[2].querySelector('.el-cascader-menu__item');
|
||||||
|
item3.click();
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
|
||||||
|
expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
|
||||||
|
expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
|
||||||
|
expect(vm.selectedOptions[2]).to.be.equal('xihu');
|
||||||
|
done();
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
it('change on select', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
change-on-select
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
vm.$el.click();
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
|
||||||
|
|
||||||
|
const menu = vm.$refs.cascader.menu;
|
||||||
|
const menuElm = menu.$el;
|
||||||
|
const item1 = menuElm.querySelector('.el-cascader-menu__item');
|
||||||
|
|
||||||
|
item1.click();
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(2);
|
||||||
|
expect(item1.classList.contains('is-active')).to.be.true;
|
||||||
|
expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
|
||||||
|
|
||||||
|
const item2 = menuElm.children[1].querySelector('.el-cascader-menu__item');
|
||||||
|
item2.click();
|
||||||
|
|
||||||
|
menu.$nextTick(_ => {
|
||||||
|
expect(menuElm.children.length).to.be.equal(3);
|
||||||
|
expect(item2.classList.contains('is-active')).to.be.true;
|
||||||
|
expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
|
||||||
|
|
||||||
|
const item3 = menuElm.children[2].querySelector('.el-cascader-menu__item');
|
||||||
|
item3.click();
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
|
||||||
|
expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
|
||||||
|
expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
|
||||||
|
expect(vm.selectedOptions[2]).to.be.equal('xihu');
|
||||||
|
done();
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
it('filterable', done => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-cascader
|
||||||
|
ref="cascader"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="options"
|
||||||
|
filterable
|
||||||
|
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: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
expect(vm.$el).to.be.exist;
|
||||||
|
vm.$refs.cascader.inputValue = 'z';
|
||||||
|
vm.$el.click();
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
|
||||||
|
|
||||||
|
const menu = vm.$refs.cascader.menu;
|
||||||
|
const menuElm = menu.$el;
|
||||||
|
const item1 = menuElm.querySelector('.el-cascader-menu__item');
|
||||||
|
|
||||||
|
expect(menuElm.children.length).to.be.equal(1);
|
||||||
|
expect(menuElm.children[0].children.length).to.be.equal(1);
|
||||||
|
done();
|
||||||
|
|
||||||
|
item1.click();
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
|
||||||
|
expect(vm.selectedOptions[0]).to.be.equal('zhejiang');
|
||||||
|
expect(vm.selectedOptions[1]).to.be.equal('hangzhou');
|
||||||
|
expect(vm.selectedOptions[2]).to.be.equal('xihu');
|
||||||
|
done();
|
||||||
|
}, 500);
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue