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 @@ + + + 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); + }); +});