diff --git a/components.json b/components.json
index 966d4a473..314321185 100644
--- a/components.json
+++ b/components.json
@@ -58,5 +58,6 @@
"scrollbar": "./packages/scrollbar/index.js",
"carousel-item": "./packages/carousel-item/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"
}
diff --git a/examples/docs/en-US/cascader.md b/examples/docs/en-US/cascader.md
new file mode 100644
index 000000000..3eb74a6f2
--- /dev/null
+++ b/examples/docs/en-US/cascader.md
@@ -0,0 +1,487 @@
+
+
+
+
+## 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
+
+
+```
+:::
+
+### Disabled option
+
+:::demo
+```html
+
+
+```
+:::
+
+### Default Value
+
+:::demo default value is assigned by an array type value.
+```html
+
+
+```
+:::
+
+### Size
+
+:::demo
+```html
+
+
+
+
+
+
+```
+:::
+
+### Hover to expand
+
+Hover to expand the next level options, click to select option.
+
+:::demo
+```html
+
+
+```
+:::
+
+### Change on select
+
+Allow only select parent options.
+
+:::demo
+```html
+
+
+```
+:::
+
+### Search
+
+Search and select options directly.
+
+:::demo
+```html
+
+
+```
+:::
+
+### 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 |
\ No newline at end of file
diff --git a/examples/docs/zh-CN/cascader.md b/examples/docs/zh-CN/cascader.md
new file mode 100644
index 000000000..7281daca5
--- /dev/null
+++ b/examples/docs/zh-CN/cascader.md
@@ -0,0 +1,491 @@
+
+
+
+
+## 级联选择
+
+需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。
+
+从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。
+
+### 基本使用
+
+:::demo
+```html
+
+
+```
+:::
+
+### 禁用选项
+
+通过在数据源中设置 `disabled` 字段来声明该选项时禁用的
+
+:::demo
+```html
+
+
+```
+:::
+
+### 默认值
+
+:::demo 默认值通过数组的方式指定。
+```html
+
+
+```
+:::
+
+### 尺寸
+
+:::demo 提供三种尺寸的级联选择器
+```html
+
+
+
+
+
+
+```
+:::
+
+### 移入展开
+
+在鼠标移入时就展开下级菜单,完成选择仍需要进行点击。
+
+:::demo
+```html
+
+
+```
+:::
+
+### 选择即改变
+
+该模式下允许只选中父级选项。
+
+:::demo
+```html
+
+
+```
+:::
+
+### 可搜索
+
+可以直接搜索选项并选择。
+
+:::demo
+```html
+
+
+```
+:::
+
+### 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 | 当绑定值变化时触发的事件 | 当前值 |
\ No newline at end of file
diff --git a/examples/nav.config.json b/examples/nav.config.json
index 9f78e055f..f2caa17fe 100644
--- a/examples/nav.config.json
+++ b/examples/nav.config.json
@@ -76,6 +76,10 @@
"path": "/select",
"title": "Select 选择器"
},
+ {
+ "path": "/cascader",
+ "title": "Cascader 级联选择"
+ },
{
"path": "/switch",
"title": "Switch 开关"
@@ -298,6 +302,10 @@
"path": "/select",
"title": "Select"
},
+ {
+ "path": "/cascader",
+ "title": "Cascader"
+ },
{
"path": "/switch",
"title": "Switch"
diff --git a/packages/cascader/cooking.conf.js b/packages/cascader/cooking.conf.js
new file mode 100644
index 000000000..3bbec53de
--- /dev/null
+++ b/packages/cascader/cooking.conf.js
@@ -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();
diff --git a/packages/cascader/index.js b/packages/cascader/index.js
new file mode 100644
index 000000000..68163ac5e
--- /dev/null
+++ b/packages/cascader/index.js
@@ -0,0 +1,8 @@
+import Cascader from './src/main';
+
+/* istanbul ignore next */
+Cascader.install = function(Vue) {
+ Vue.component(Cascader.name, Cascader);
+};
+
+export default Cascader;
diff --git a/packages/cascader/package.json b/packages/cascader/package.json
new file mode 100644
index 000000000..65e1961f9
--- /dev/null
+++ b/packages/cascader/package.json
@@ -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": {}
+}
diff --git a/packages/cascader/src/main.vue b/packages/cascader/src/main.vue
new file mode 100644
index 000000000..d96ea3ae0
--- /dev/null
+++ b/packages/cascader/src/main.vue
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+ {{displayValue}}
+
+
+
+
diff --git a/packages/cascader/src/menu.vue b/packages/cascader/src/menu.vue
new file mode 100644
index 000000000..ab864df5f
--- /dev/null
+++ b/packages/cascader/src/menu.vue
@@ -0,0 +1,148 @@
+
\ No newline at end of file
diff --git a/packages/theme-default/src/cascader.css b/packages/theme-default/src/cascader.css
index a79fe34e2..35dc81e7d 100644
--- a/packages/theme-default/src/cascader.css
+++ b/packages/theme-default/src/cascader.css
@@ -1,44 +1,163 @@
@charset "UTF-8";
@import "./input.css";
@import "./common/var.css";
-/*@import "./core/dropdown.css";*/
-@component-namespace element {
+@component-namespace el {
@b cascader {
display: inline-block;
position: relative;
+ background-color: #fff;
- @e dropdown {
- background-color: var(--cascader-menu-fill);
- border: var(--cascader-menu-border);
- border-radius: var(--cascader-menu-radius);
- box-shadow: var(--cascader-menu-submenu-shadow);
- margin-top: 5px;
- max-height: var(--cascader-height);
+ .el-input,
+ .el-input__inner {
+ cursor: pointer;
+ background-color: transparent;
+ z-index: 1;
+ }
+
+ .el-input__icon {
+ transition: none;
+ }
+
+ .el-icon-caret-bottom {
+ transition: transform .3s;
+
+ @when reverse {
+ transform: rotateZ(180deg);
+ }
+ }
+
+ @e label {
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;
- z-index: 10;
- }
-
- @e wrap {
+ text-overflow: ellipsis;
overflow: hidden;
+ box-sizing: border-box;
+ cursor: pointer;
}
- @e menu {
- border: 0;
- box-shadow: none;
- display: inline-block;
- margin: 0;
- position: relative;
- vertical-align: top;
+ @m large {
+ font-size: var(--input-large-font-size);
- &::before {
- border-left: var(--cascader-menu-border);
- content: " ";
- height: var(--cascader-height);
- left: 0;
- position: absolute;
+ .el-cascader__label {
+ line-height: calc(var(--input-large-height) - 2);
+ }
+ }
+ @m small {
+ 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;
}
}
}
diff --git a/packages/theme-default/src/common/var.css b/packages/theme-default/src/common/var.css
index 25e94e381..c6d0e68e7 100644
--- a/packages/theme-default/src/common/var.css
+++ b/packages/theme-default/src/common/var.css
@@ -161,6 +161,7 @@
--select-option-color: var(--link-color);
--select-option-disabled-color: var(--color-extra-light-silver);
+ --select-option-disabled-background: var(--color-white);
--select-option-height: 36px;
--select-option-hover-background: var(--color-light-gray);
--select-option-selected: var(--color-primary);
diff --git a/packages/theme-default/src/index.css b/packages/theme-default/src/index.css
index 544ee48d7..67e499d73 100644
--- a/packages/theme-default/src/index.css
+++ b/packages/theme-default/src/index.css
@@ -44,3 +44,4 @@
@import "./carousel.css";
@import "./carousel-item.css";
@import "./collapse.css";
+@import "./cascader.css";
diff --git a/src/index.js b/src/index.js
index cfa8c6c8d..36fd0fefc 100644
--- a/src/index.js
+++ b/src/index.js
@@ -60,6 +60,7 @@ import Scrollbar from '../packages/scrollbar';
import CarouselItem from '../packages/carousel-item';
import Collapse from '../packages/collapse';
import CollapseItem from '../packages/collapse-item';
+import Cascader from '../packages/cascader';
import locale from 'element-ui/src/locale';
const components = [
@@ -118,7 +119,8 @@ const components = [
Scrollbar,
CarouselItem,
Collapse,
- CollapseItem
+ CollapseItem,
+ Cascader
];
const install = function(Vue, opts = {}) {
@@ -211,5 +213,6 @@ module.exports = {
Scrollbar,
CarouselItem,
Collapse,
- CollapseItem
+ CollapseItem,
+ Cascader
};
diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js
index c8b63b5af..701b9d00c 100644
--- a/src/locale/lang/en.js
+++ b/src/locale/lang/en.js
@@ -56,6 +56,10 @@ export default {
noData: 'No data',
placeholder: 'Select'
},
+ cascader: {
+ noMatch: 'No matching data',
+ placeholder: 'Select'
+ },
pagination: {
goto: 'Go to',
pagesize: '/page',
diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js
index ce927f132..5cc3050df 100644
--- a/src/locale/lang/zh-CN.js
+++ b/src/locale/lang/zh-CN.js
@@ -56,6 +56,10 @@ export default {
noData: '无数据',
placeholder: '请选择'
},
+ cascader: {
+ noMatch: '无匹配数据',
+ placeholder: '请选择'
+ },
pagination: {
goto: '前往',
pagesize: '条/页',
diff --git a/src/utils/vue-popper.js b/src/utils/vue-popper.js
index 18c02c8f6..0b5ee1504 100644
--- a/src/utils/vue-popper.js
+++ b/src/utils/vue-popper.js
@@ -83,6 +83,7 @@ export default {
this.$slots.reference[0]) {
reference = this.referenceElm = this.$slots.reference[0].elm;
}
+
if (!popper || !reference) return;
if (this.visibleArrow) this.appendArrow(popper);
if (this.appendToBody) document.body.appendChild(this.popperElm);
diff --git a/test/unit/specs/cascader.spec.js b/test/unit/specs/cascader.spec.js
new file mode 100644
index 000000000..007cbb907
--- /dev/null
+++ b/test/unit/specs/cascader.spec.js
@@ -0,0 +1,524 @@
+import { createVue, destroyVM, triggerEvent } from '../util';
+
+describe('Cascader', () => {
+ let vm;
+ afterEach(() => {
+ destroyVM(vm);
+ });
+
+ it('create', done => {
+ vm = createVue({
+ template: `
+
+ `,
+ 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: `
+
+ `,
+ 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: `
+
+ `,
+ 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: `
+
+ `,
+ 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: `
+
+ `,
+ 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: `
+
+ `,
+ 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: `
+
+ `,
+ 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);
+ });
+});