Merge branch 'dev' into carbon

pull/5997/head
Leopoldthecoder 2017-07-20 20:51:59 +08:00
commit 96f542e024
44 changed files with 948 additions and 226 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ examples/pages/zh-CN
fe.element/element-ui
.npmrc
coverage
waiter.config.js

View File

@ -1,6 +1,6 @@
var fs = require('fs');
var path = require('path');
var version = process.env.VERSION || require('../../package.json').version;
var content = { '1.0.9': '1.0', '1.1.6': '1.1', '1.2.9': '1.2' };
if (!content[version]) content[version] = '1.3';
var content = { '1.0.9': '1.0', '1.1.6': '1.1', '1.2.9': '1.2', '1.3.7': '1.3' };
if (!content[version]) content[version] = '1.4';
fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content));

View File

@ -42,7 +42,7 @@ if [ "$TRAVIS_TAG" ]; then
export SUB_FOLDER=$(echo "$TRAVIS_TAG" | grep -o -E "\d+\.\d+")
echo $SUB_FOLDER
SUB_FOLDER='1.3'
SUB_FOLDER='1.4'
mkdir $SUB_FOLDER
rm -rf *.js *.css *.map static
rm -rf $SUB_FOLDER/**

View File

@ -107,6 +107,7 @@
background-color: #ECF8FF;
border-radius: 4px;
border-left: #50bfff 5px solid;
margin-top: 20px;
code {
background-color: rgba(#fff, .7);

View File

@ -243,7 +243,7 @@ Checkbox with button styles.
| min | minimum number of checkbox checked | number | — | — |
| max | maximum number of checkbox checked | number | — | — |
### Checkbox-group Events
### Checkbox Events
| Event Name | Description | Parameters |
|---------- |-------- |---------- |
| change | triggers when the binding value changes | Event object |

View File

@ -3,7 +3,7 @@
.el-menu-demo {
padding-left: 55px;
}
.el-menu-vertical-demo {
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
@ -33,7 +33,8 @@
data() {
return {
activeIndex: '1',
activeIndex2: '1'
activeIndex2: '1',
isCollapse: false
};
},
methods: {
@ -179,10 +180,70 @@ Vertical NavMenu with sub-menus.
```
:::
### Collapse
Vertical NavMenu could be collapsed.
::: demo
```html
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
<el-radio-button :label="false">expand</el-radio-button>
<el-radio-button :label="true">collapse</el-radio-button>
</el-radio-group>
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-message"></i>
<span slot="title">Navigator One</span>
</template>
<el-menu-item-group>
<span slot="title">Group One</span>
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item two</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<span slot="title">item four</span>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">Navigator Two</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<span slot="title">Navigator Three</span>
</el-menu-item>
</el-menu>
<script>
export default {
data() {
return {
isCollapse: false
};
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
```
:::
### Menu Attribute
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------- |---------- |------------- |-------- |
| mode | menu display mode | string | horizontal/vertical | vertical |
| collapse | whether the menu is collapsed (available only in vertical mode) | boolean | — | false |
| theme | theme color | string | light/dark | light |
| default-active | index of currently active menu | string | — | — |
| default-openeds | array that contains keys of currently active sub-menus | Array | — | — |

View File

@ -637,11 +637,16 @@ Create and select new items that are not included in select options
```
:::
:::tip
If the binding value of Select is an object, make sure to assign `value-key` as its unique identity key name.
:::
### Select Attributes
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| multiple | whether multiple-select is activated | boolean | — | false |
| disabled | whether Select is disabled | boolean | — | false |
| value-key | unique identity key name for value, required when value is an object | string | — | value |
| size | size of Input | string | large/small/mini | — |
| clearable | whether single select can be cleared | boolean | — | false |
| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | number | — | 0 |

View File

@ -93,6 +93,35 @@
}]
}];
const data3 = [{
id: 1,
label: 'Level one 1',
children: [{
id: 3,
label: 'Level two 2-1',
children: [{
id: 4,
label: 'Level three 3-1-1'
}, {
id: 5,
label: 'Level three 3-1-2',
disabled: true
}]
}, {
id: 2,
label: 'Level two 2-2',
disabled: true,
children: [{
id: 6,
label: 'Level three 3-2-1'
}, {
id: 7,
label: 'Level three 3-2-2',
disabled: true
}]
}]
}];
let id = 1000;
const regions = [{
@ -211,6 +240,7 @@
return {
data,
data2,
data3,
regions,
defaultProps,
props,
@ -363,6 +393,63 @@ Used for node selection. In the following example, data for each layer is acquir
```
:::
### Disabled checkbox
The checkbox of a node can be set as disabled.
::: demo In the example, 'disabled' property is declared in defaultProps, and some nodes are set as 'disabled:true'. The corresponding checkboxes are disabled and can't be clicked.
```html
<el-tree
:data="data3"
:props="defaultProps"
show-checkbox
@check-change="handleCheckChange">
</el-tree>
<script>
export default {
data() {
return {
data3: [{
id: 1,
label: 'Level one 1',
children: [{
id: 3,
label: 'Level two 2-1',
children: [{
id: 4,
label: 'Level three 3-1-1'
}, {
id: 5,
label: 'Level three 3-1-2',
disabled: true
}]
}, {
id: 2,
label: 'Level two 2-2',
disabled: true,
children: [{
id: 6,
label: 'Level three 3-2-1'
}, {
id: 7,
label: 'Level three 3-2-2',
disabled: true
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label',
disabled: 'disabled',
},
};
}
};
</script>
```
:::
### Default expanded and default checked
Tree nodes can be initially expanded or checked
@ -789,8 +876,9 @@ Only one node among the same level can be expanded at one time.
### props
| Attribute | Description | Type | Accepted Values | Default |
| --------- | ---------------------------------------- | ------ | --------------- | ------- |
| label | specify which key of node object is used as the node's label | string | — | — |
| children | specify which key of node object is used as the node's subtree | string | — | — |
| label | specify which key of node object is used as the node's label | string, function(data, node) | — | — |
| children | specify which node object is used as the node's subtree | string, function(data, node) | — | — |
| disabled | specify which node's checkbox disabled | boolean, function(data, node) | — | — |
### Method
`Tree` has the following method, which returns the currently selected array of nodes.

View File

@ -254,7 +254,7 @@
| min | 可被勾选的 checkbox 的最小数量 | number | — | — |
| max | 可被勾选的 checkbox 的最大数量 | number | — | — |
### Checkbox-group Events
### Checkbox Events
| 事件名称 | 说明 | 回调参数 |
|---------- |-------- |---------- |
| change | 当绑定值变化时触发的事件 | event 事件对象 |

View File

@ -3,7 +3,7 @@
.el-menu-demo {
padding-left: 55px;
}
.el-menu-vertical-demo {
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
@ -33,7 +33,8 @@
data() {
return {
activeIndex: '1',
activeIndex2: '1'
activeIndex2: '1',
isCollapse: true
};
},
methods: {
@ -181,10 +182,68 @@
```
:::
### 折叠
::: demo
```html
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
<el-radio-button :label="false">展开</el-radio-button>
<el-radio-button :label="true">收起</el-radio-button>
</el-radio-group>
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-message"></i>
<span slot="title">导航一</span>
</template>
<el-menu-item-group>
<span slot="title">分组一</span>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<span slot="title">选项4</span>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-setting"></i>
<span slot="title">导航三</span>
</el-menu-item>
</el-menu>
<script>
export default {
data() {
return {
isCollapse: false
};
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
```
:::
### Menu Attribute
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| mode | 模式 | string | horizontal,vertical | vertical |
| collapse | 是否水平折叠收起菜单(仅在 mode 为 vertical 时可用)| boolean | — | false |
| theme | 主题色 | string | light,dark | light |
| default-active | 当前激活菜单的 index | string | — | — |
| default-openeds | 当前打开的submenu的 key 数组 | Array | — | — |

View File

@ -632,11 +632,16 @@
```
:::
:::tip
如果 Select 的绑定值为对象类型,请务必指定 `value-key` 作为它的唯一性标识。
:::
### Select Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| multiple | 是否多选 | boolean | — | false |
| disabled | 是否禁用 | boolean | — | false |
| value-key | 作为 value 唯一标识的键名,绑定值为对象类型时必填 | string | — | value |
| size | 输入框尺寸 | string | large/small/mini | — |
| clearable | 单选时是否可以清空选项 | boolean | — | false |
| multiple-limit | 多选时用户最多可以选择的项目数,为 0 则不限制 | number | — | 0 |

View File

@ -93,6 +93,35 @@
}]
}];
const data3 = [{
id: 1,
label: '一级 2',
children: [{
id: 3,
label: '二级 2-1',
children: [{
id: 4,
label: '三级 3-1-1'
}, {
id: 5,
label: '三级 3-1-2',
disabled: true
}]
}, {
id: 2,
label: '二级 2-2',
disabled: true,
children: [{
id: 6,
label: '三级 3-2-1'
}, {
id: 7,
label: '三级 3-2-2',
disabled: true
}]
}]
}];
let id = 1000;
const regions = [{
@ -211,6 +240,7 @@
return {
data,
data2,
data3,
regions,
defaultProps,
props,
@ -427,6 +457,62 @@
```
:::
### 禁用状态
可将 Tree 的某些节点设置为禁用状态
::: demo 通过`disabled`设置禁用状态。
```html
<el-tree
:data="data3"
show-checkbox
node-key="id"
:default-expanded-keys="[2, 3]"
:default-checked-keys="[5]">
</el-tree>
<script>
export default {
data() {
return {
data3: [{
id: 1,
label: '一级 2',
children: [{
id: 3,
label: '二级 2-1',
children: [{
id: 4,
label: '三级 3-1-1'
}, {
id: 5,
label: '三级 3-1-2',
disabled: true
}]
}, {
id: 2,
label: '二级 2-2',
disabled: true,
children: [{
id: 6,
label: '三级 3-2-1'
}, {
id: 7,
label: '三级 3-2-2',
disabled: true
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
}
};
</script>
```
:::
### 树节点的选择
::: demo 本例展示如何获取和设置选中节点。获取和设置各有两种方式:通过 node 或通过 key。如果需要通过 key 来获取或设置,则必须设置`node-key`。
@ -789,8 +875,9 @@
### props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| -------- | ----------------- | ------ | ---- | ---- |
| label | 指定节点标签为节点对象的某个属性值 | string | — | — |
| children | 指定子树为节点对象的某个属性值 | string | — | — |
| label | 指定节点标签为节点对象的某个属性值 | string, function(data, node) | — | — |
| children | 指定子树为节点对象的某个属性值 | string, function(data, node) | — | — |
| disabled | 指定节点选择框是否禁用 | boolean, function(data, node) | — | — |
### 方法
`Tree` 拥有如下方法,返回目前被选中的节点数组:

View File

@ -1 +1 @@
{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3"}
{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.0-beta.1":"1.4"}

View File

@ -1,6 +1,6 @@
{
"name": "element-ui",
"version": "1.3.7",
"version": "1.4.0-beta.1",
"description": "A Component Library for Vue.js.",
"main": "lib/element-ui.common.js",
"files": [

View File

@ -1,5 +1,6 @@
<script>
import { isDef } from 'element-ui/src/utils/shared';
import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
export default {
name: 'ElCascaderMenu',
@ -94,6 +95,12 @@
} else {
this.$emit('activeItemChange', this.activeValue);
}
},
scrollMenu(menu) {
scrollIntoView(menu, menu.getElementsByClassName('is-active')[0]);
},
handleMenuEnter() {
this.$nextTick(() => this.$refs.menus.forEach(menu => this.scrollMenu(menu)));
}
},
@ -121,9 +128,19 @@
click: 'click',
hover: 'mouseenter'
}[expandTrigger];
events.on[triggerEvent] = () => { this.activeItem(item, menuIndex); };
events.on[triggerEvent] = () => {
this.activeItem(item, menuIndex);
this.$nextTick(() => {
// adjust self and next level
this.scrollMenu(this.$refs.menus[menuIndex]);
this.scrollMenu(this.$refs.menus[menuIndex + 1]);
});
};
} else {
events.on.click = () => { this.select(item, menuIndex); };
events.on.click = () => {
this.select(item, menuIndex);
this.$nextTick(() => this.scrollMenu(this.$refs.menus[menuIndex]));
};
}
}
@ -152,19 +169,22 @@
'el-cascader-menu': true,
'el-cascader-menu--flexible': isFlat
}}
style={menuStyle}>
style={menuStyle}
refInFor
ref="menus">
{items}
</ul>
);
});
return (
<transition name="el-zoom-in-top" on-after-leave={this.handleMenuLeave}>
<transition name="el-zoom-in-top" on-before-enter={this.handleMenuEnter} on-after-leave={this.handleMenuLeave}>
<div
v-show={visible}
class={[
'el-cascader-menus',
popperClass
]}
ref="wrapper"
>
{menus}
</div>

View File

@ -63,11 +63,29 @@
methods: {
getCellStyle(month) {
const style = {};
const date = new Date(this.date);
var year = this.date.getFullYear();
var date = new Date(0);
date.setFullYear(year);
date.setMonth(month);
style.disabled = typeof this.disabledDate === 'function' &&
this.disabledDate(date);
date.setHours(0);
var nextMonth = new Date(date);
nextMonth.setMonth(month + 1);
var flag = false;
if (typeof this.disabledDate === 'function') {
while (date < nextMonth) {
if (this.disabledDate(date)) {
date = new Date(date.getTime() + 8.64e7);
} else {
break;
}
}
if ((date - nextMonth) === 0) flag = true;
}
style.disabled = flag;
style.current = this.month === month;
return style;

View File

@ -62,11 +62,28 @@
methods: {
getCellStyle(year) {
const style = {};
const date = new Date(this.date);
var date = new Date(0);
date.setFullYear(year);
style.disabled = typeof this.disabledDate === 'function' &&
this.disabledDate(date);
date.setHours(0);
var nextYear = new Date(date);
nextYear.setFullYear(year + 1);
var flag = false;
if (typeof this.disabledDate === 'function') {
while (date < nextYear) {
if (this.disabledDate(date)) {
date = new Date(date.getTime() + 8.64e7);
} else {
break;
}
}
if ((date - nextYear) === 0) flag = true;
}
style.disabled = flag;
style.current = Number(this.year) === year;
return style;

View File

@ -406,11 +406,11 @@
visibleDate: {
get() {
return formatDate(this.date);
return formatDate(this.date, this.dateFormat);
},
set(val) {
const date = parseDate(val, 'yyyy-MM-dd');
const date = parseDate(val, this.dateFormat);
if (!date) {
return;
}
@ -445,6 +445,14 @@
} else {
return 'HH:mm:ss';
}
},
dateFormat() {
if (this.format) {
return this.format.replace('HH:mm', '').replace(':ss', '').trim();
} else {
return 'yyyy-MM-dd';
}
}
}
};

View File

@ -1,6 +1,7 @@
<template>
<transition name="el-zoom-in-top" @after-leave="$emit('dodestroy')">
<transition name="el-zoom-in-top" @before-enter="handleMenuEnter" @after-leave="$emit('dodestroy')">
<div
ref="popper"
v-show="visible"
:style="{ width: width + 'px' }"
:class="popperClass"
@ -18,6 +19,7 @@
<script type="text/babel">
import ElScrollbar from 'element-ui/packages/scrollbar';
import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
const parseTime = function(time) {
const values = ('' || time).split(':');
@ -81,6 +83,7 @@
} else if (this.maxTime && compareTime(val, this.maxTime) > 0) {
this.$emit('pick');
}
this.$nextTick(() => this.scrollToOption());
}
},
@ -93,6 +96,15 @@
handleClear() {
this.$emit('pick');
},
scrollToOption(className = 'selected') {
const menu = this.$refs.popper.querySelector('.el-picker-panel__content');
scrollIntoView(menu, menu.getElementsByClassName(className)[0]);
},
handleMenuEnter() {
this.$nextTick(() => this.scrollToOption());
}
},

View File

@ -179,7 +179,7 @@ const TYPE_VALUE_RESOLVER_MAP = {
};
const PLACEMENT_MAP = {
left: 'bottom-start',
center: 'bottom-center',
center: 'bottom',
right: 'bottom-end'
};

View File

@ -4,7 +4,7 @@
'is-validating': validateState === 'validating',
'is-required': isRequired || required
}">
<label :for="prop" class="el-form-item__label" v-bind:style="labelStyle" v-if="label">
<label :for="prop" class="el-form-item__label" v-bind:style="labelStyle" v-if="label || $slots.label">
<slot name="label">{{label + form.labelSuffix}}</slot>
</label>
<div class="el-form-item__content" v-bind:style="contentStyle">

View File

@ -15,6 +15,7 @@
componentName: 'ElMenuItemGroup',
inject: ['rootMenu'],
props: {
title: {
type: String
@ -29,6 +30,7 @@
levelPadding() {
let padding = 10;
let parent = this.$parent;
if (this.rootMenu.collapse) return 20;
while (parent && parent.$options.componentName !== 'ElMenu') {
if (parent.$options.componentName === 'ElSubmenu') {
padding += 20;

View File

@ -6,7 +6,19 @@
'is-active': active,
'is-disabled': disabled
}">
<slot></slot>
<el-tooltip
v-if="$parent === rootMenu && rootMenu.collapse"
effect="dark"
placement="right">
<div slot="content"><slot name="title"></slot></div>
<div style="position: absolute;left: 0;top: 0;height: 100%;width: 100%;display: inline-block;box-sizing: border-box;padding: 0 20px;">
<slot></slot>
</div>
</el-tooltip>
<template v-else>
<slot></slot>
<slot name="title"></slot>
</template>
</li>
</template>
<script>

View File

@ -36,11 +36,16 @@ export default {
let padding = 20;
let parent = this.$parent;
while (parent && parent.$options.componentName !== 'ElMenu') {
if (parent.$options.componentName === 'ElSubmenu') {
padding += 20;
if (this.rootMenu.collapse) {
padding = 20;
} else {
while (parent && parent.$options.componentName !== 'ElMenu') {
if (parent.$options.componentName === 'ElSubmenu') {
padding += 20;
}
parent = parent.$parent;
}
parent = parent.$parent;
}
return {paddingLeft: padding + 'px'};
}

View File

@ -1,15 +1,82 @@
<template>
<ul class="el-menu"
:class="{
'el-menu--horizontal': mode === 'horizontal',
'el-menu--dark': theme === 'dark'
}"
>
<slot></slot>
</ul>
<el-menu-collapse-transition>
<ul class="el-menu"
:key="+collapse"
:class="{
'el-menu--horizontal': mode === 'horizontal',
'el-menu--dark': theme === 'dark',
'el-menu--collapse': collapse
}"
>
<slot></slot>
</ul>
</el-menu-collapse-transition>
</template>
<script>
import Vue from 'vue';
import emitter from 'element-ui/src/mixins/emitter';
import { addClass, removeClass, hasClass } from 'element-ui/src/utils/dom';
Vue.component('el-menu-collapse-transition', {
functional: true,
render(createElement, context) {
const data = {
props: {
mode: 'out-in'
},
on: {
beforeEnter(el) {
el.style.opacity = 0.2;
},
enter(el) {
addClass(el, 'el-opacity-transition');
el.style.opacity = 1;
},
afterEnter(el) {
removeClass(el, 'el-opacity-transition');
el.style.opacity = '';
},
beforeLeave(el) {
if (!el.dataset) el.dataset = {};
if (hasClass(el, 'el-menu--collapse')) {
removeClass(el, 'el-menu--collapse');
el.dataset.oldOverflow = el.style.overflow;
el.dataset.scrollWidth = el.scrollWidth;
addClass(el, 'el-menu--collapse');
}
el.style.width = el.scrollWidth + 'px';
el.style.overflow = 'hidden';
},
leave(el) {
if (!hasClass(el, 'el-menu--collapse')) {
addClass(el, 'horizontal-collapse-transition');
el.style.width = '64px';
} else {
addClass(el, 'horizontal-collapse-transition');
el.style.width = el.dataset.scrollWidth + 'px';
}
},
afterLeave(el) {
removeClass(el, 'horizontal-collapse-transition');
if (hasClass(el, 'el-menu--collapse')) {
el.style.width = el.dataset.scrollWidth + 'px';
} else {
el.style.width = '64px';
}
el.style.overflow = el.dataset.oldOverflow;
}
}
};
return createElement('transition', data, context.children);
}
});
export default {
name: 'ElMenu',
@ -18,6 +85,12 @@
mixins: [emitter],
provide() {
return {
rootMenu: this
};
},
props: {
mode: {
type: String,
@ -37,7 +110,8 @@
menuTrigger: {
type: String,
default: 'hover'
}
},
collapse: Boolean
},
data() {
return {
@ -106,7 +180,7 @@
this.activedIndex = item.index;
this.$emit('select', index, indexPath, item);
if (this.mode === 'horizontal') {
if (this.mode === 'horizontal' || this.collapse) {
this.openedMenus = [];
}

View File

@ -5,18 +5,21 @@
'is-active': active,
'is-opened': opened
}"
@mouseenter="handleMouseenter"
@mouseleave="handleMouseleave"
>
<div class="el-submenu__title" ref="submenu-title" :style="paddingStyle">
<div class="el-submenu__title" ref="submenu-title" @click="handleClick" :style="paddingStyle">
<slot name="title"></slot>
<i :class="{
'el-submenu__icon-arrow': true,
'el-icon-arrow-down': rootMenu.mode === 'vertical',
'el-icon-caret-bottom': rootMenu.mode === 'horizontal'
'el-icon-caret-bottom': rootMenu.mode === 'horizontal',
'el-icon-arrow-down': rootMenu.mode === 'vertical' && !rootMenu.collapse,
'el-icon-caret-right': rootMenu.mode === 'vertical' && rootMenu.collapse
}">
</i>
</div>
<template v-if="rootMenu.mode === 'horizontal'">
<transition name="el-zoom-in-top">
<template v-if="rootMenu.mode === 'horizontal' || (rootMenu.mode === 'vertical' && rootMenu.collapse)">
<transition :name="menuTransitionName">
<ul class="el-menu" v-show="opened"><slot></slot></ul>
</transition>
</template>
@ -45,6 +48,7 @@
required: true
}
},
data() {
return {
timeout: null,
@ -53,6 +57,9 @@
};
},
computed: {
menuTransitionName() {
return this.rootMenu.collapse ? 'el-zoom-in-left' : 'el-zoom-in-top';
},
opened() {
return this.rootMenu.openedMenus.indexOf(this.index) > -1;
},
@ -93,37 +100,40 @@
delete this.submenus[item.index];
},
handleClick() {
const {rootMenu} = this;
if (
(rootMenu.menuTrigger === 'hover' && rootMenu.mode === 'horizontal') ||
(rootMenu.collapse && rootMenu.mode === 'vertical')
) {
return;
}
this.dispatch('ElMenu', 'submenu-click', this);
},
handleMouseenter() {
const {rootMenu} = this;
if (
(rootMenu.menuTrigger === 'click' && rootMenu.mode === 'horizontal') ||
(!rootMenu.collapse && rootMenu.mode === 'vertical')
) {
return;
}
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.rootMenu.openMenu(this.index, this.indexPath);
}, 300);
},
handleMouseleave() {
const {rootMenu} = this;
if (
(rootMenu.menuTrigger === 'click' && rootMenu.mode === 'horizontal') ||
(!rootMenu.collapse && rootMenu.mode === 'vertical')
) {
return;
}
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.rootMenu.closeMenu(this.index, this.indexPath);
}, 300);
},
initEvents() {
let {
rootMenu,
handleMouseenter,
handleMouseleave,
handleClick
} = this;
let triggerElm;
if (rootMenu.mode === 'horizontal' && rootMenu.menuTrigger === 'hover') {
triggerElm = this.$el;
triggerElm.addEventListener('mouseenter', handleMouseenter);
triggerElm.addEventListener('mouseleave', handleMouseleave);
} else {
triggerElm = this.$refs['submenu-title'];
triggerElm.addEventListener('click', handleClick);
}
}
},
created() {
@ -133,9 +143,6 @@
beforeDestroy() {
this.parentMenu.removeSubmenu(this);
this.rootMenu.removeSubmenu(this);
},
mounted() {
this.initEvents();
}
};
</script>

View File

@ -17,6 +17,7 @@
<script type="text/babel">
import Emitter from 'element-ui/src/mixins/emitter';
import { getValueByPath } from 'element-ui/src/utils/util';
export default {
mixins: [Emitter],
@ -47,8 +48,13 @@
},
computed: {
isObject() {
const type = typeof this.value;
return type !== 'string' && type !== 'number' && type !== 'boolean';
},
currentLabel() {
return this.label || ((typeof this.value === 'string' || typeof this.value === 'number') ? this.value : '');
return this.label || (this.isObject ? '' : this.value);
},
currentValue() {
@ -65,9 +71,9 @@
itemSelected() {
if (!this.parent.multiple) {
return this.value === this.parent.value;
return this.isEqual(this.value, this.parent.value);
} else {
return this.parent.value.indexOf(this.value) > -1;
return this.contains(this.parent.value, this.value);
}
},
@ -92,6 +98,26 @@
},
methods: {
isEqual(a, b) {
if (!this.isObject) {
return a === b;
} else {
const valueKey = this.parent.valueKey;
return getValueByPath(a, valueKey) === getValueByPath(b, valueKey);
}
},
contains(arr = [], target) {
if (!this.isObject) {
return arr.indexOf(target) > -1;
} else {
const valueKey = this.parent.valueKey;
return arr.some(item => {
return getValueByPath(item, valueKey) === getValueByPath(target, valueKey);
});
}
},
handleGroupDisabled(val) {
this.groupDisabled = val;
},

View File

@ -11,7 +11,7 @@
<transition-group @after-leave="resetInputHeight">
<el-tag
v-for="item in selected"
:key="item.value"
:key="getValueKey(item)"
closable
:hit="item.hitState"
type="primary"
@ -67,8 +67,8 @@
</el-input>
<transition
name="el-zoom-in-top"
@after-leave="doDestroy"
@after-enter="handleMenuEnter">
@before-enter="handleMenuEnter"
@after-leave="doDestroy">
<el-select-menu
ref="popper"
v-show="visible && emptyText !== false">
@ -105,6 +105,9 @@
import { addClass, removeClass, hasClass } from 'element-ui/src/utils/dom';
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
import { t } from 'element-ui/src/locale';
import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
import { getValueByPath } from 'element-ui/src/utils/util';
const sizeMap = {
'large': 42,
'small': 30,
@ -194,7 +197,11 @@
return t('el.select.placeholder');
}
},
defaultFirstOption: Boolean
defaultFirstOption: Boolean,
valueKey: {
type: String,
default: 'value'
}
},
data() {
@ -210,13 +217,10 @@
cachedPlaceHolder: '',
optionsCount: 0,
filteredOptionsCount: 0,
dropdownUl: null,
visible: false,
selectedLabel: '',
hoverIndex: -1,
query: '',
bottomOverflow: 0,
topOverflow: 0,
optionsAllDisabled: false,
inputHovering: false,
currentPlaceholder: ''
@ -292,7 +296,6 @@
}
});
if (!this.multiple) {
this.getOverflows();
if (this.selected) {
if (this.filterable && this.allowCreate &&
this.createdSelected && this.createdOption) {
@ -353,44 +356,31 @@
}
},
scrollToOption(className = 'selected') {
const menu = this.$refs.popper.$el.querySelector('.el-select-dropdown__wrap');
scrollIntoView(menu, menu.getElementsByClassName(className)[0]);
},
handleMenuEnter() {
if (!this.dropdownUl) {
this.dropdownUl = this.$refs.popper.$el.querySelector('.el-select-dropdown__wrap');
this.getOverflows();
}
if (!this.multiple && this.dropdownUl) {
this.resetMenuScroll();
}
},
getOverflows() {
if (this.dropdownUl && this.selected && this.selected.$el) {
let selectedRect = this.selected.$el.getBoundingClientRect();
let popperRect = this.$refs.popper.$el.getBoundingClientRect();
this.bottomOverflow = selectedRect.bottom - popperRect.bottom;
this.topOverflow = selectedRect.top - popperRect.top;
}
},
resetMenuScroll() {
if (this.bottomOverflow > 0) {
this.dropdownUl.scrollTop += this.bottomOverflow;
} else if (this.topOverflow < 0) {
this.dropdownUl.scrollTop += this.topOverflow;
}
this.$nextTick(() => this.scrollToOption());
},
getOption(value) {
let option;
const type = typeof value;
const isObject = type !== 'string' && type !== 'number' && type !== 'boolean';
for (let i = this.cachedOptions.length - 1; i >= 0; i--) {
const cachedOption = this.cachedOptions[i];
if (cachedOption.value === value) {
const isEqual = isObject
? getValueByPath(cachedOption.value, this.valueKey) === getValueByPath(value, this.valueKey)
: cachedOption.value === value;
if (isEqual) {
option = cachedOption;
break;
}
}
if (option) return option;
const label = typeof value === 'string' || typeof value === 'number'
const label = !isObject
? value : '';
let newOption = {
value: value,
@ -525,7 +515,7 @@
handleOptionSelect(option) {
if (this.multiple) {
const value = this.value.slice();
const optionIndex = value.indexOf(option.value);
const optionIndex = this.getValueIndex(value, option.value);
if (optionIndex > -1) {
value.splice(optionIndex, 1);
} else if (this.multipleLimit <= 0 || value.length < this.multipleLimit) {
@ -541,6 +531,26 @@
this.$emit('input', option.value);
this.visible = false;
}
this.$nextTick(() => this.scrollToOption());
},
getValueIndex(arr = [], value) {
const type = typeof value;
const isObject = type !== 'string' && type !== 'number' && type !== 'boolean';
if (!isObject) {
return arr.indexOf(value);
} else {
const valueKey = this.valueKey;
let index = -1;
arr.some((item, i) => {
if (getValueByPath(item, valueKey) === getValueByPath(value, valueKey)) {
index = i;
return true;
}
return false;
});
return index;
}
},
toggleMenu() {
@ -565,7 +575,6 @@
if (this.hoverIndex === this.options.length) {
this.hoverIndex = 0;
}
this.resetScrollTop();
if (this.options[this.hoverIndex].disabled === true ||
this.options[this.hoverIndex].groupDisabled === true ||
!this.options[this.hoverIndex].visible) {
@ -577,7 +586,6 @@
if (this.hoverIndex < 0) {
this.hoverIndex = this.options.length - 1;
}
this.resetScrollTop();
if (this.options[this.hoverIndex].disabled === true ||
this.options[this.hoverIndex].groupDisabled === true ||
!this.options[this.hoverIndex].visible) {
@ -585,19 +593,7 @@
}
}
}
},
resetScrollTop() {
let bottomOverflowDistance = this.options[this.hoverIndex].$el.getBoundingClientRect().bottom -
this.$refs.popper.$el.getBoundingClientRect().bottom;
let topOverflowDistance = this.options[this.hoverIndex].$el.getBoundingClientRect().top -
this.$refs.popper.$el.getBoundingClientRect().top;
if (bottomOverflowDistance > 0) {
this.dropdownUl.scrollTop += bottomOverflowDistance;
}
if (topOverflowDistance < 0) {
this.dropdownUl.scrollTop += topOverflowDistance;
}
this.$nextTick(() => this.scrollToOption('hover'));
},
selectOption() {
@ -667,6 +663,15 @@
}
}
}
},
getValueKey(item) {
const type = typeof item.value;
if (type === 'number' || type === 'string') {
return item.value;
} else {
return getValueByPath(item.value, this.valueKey);
}
}
},

View File

@ -1,7 +1,7 @@
import ElCheckbox from 'element-ui/packages/checkbox';
import ElTag from 'element-ui/packages/tag';
import objectAssign from 'element-ui/src/utils/merge';
import { getValueByPath } from './util';
import { getValueByPath } from 'element-ui/src/utils/util';
let columnIdSeed = 1;

View File

@ -312,7 +312,7 @@
},
selection() {
return this.store.selection;
return this.store.states.selection;
},
columns() {

View File

@ -1,3 +1,5 @@
import { getValueByPath } from 'element-ui/src/utils/util';
export const getCell = function(event) {
let cell = event.target;
@ -11,24 +13,6 @@ export const getCell = function(event) {
return null;
};
export const getValueByPath = function(object, prop) {
prop = prop || '';
const paths = prop.split('.');
let current = object;
let result = null;
for (let i = 0, j = paths.length; i < j; i++) {
const path = paths[i];
if (!current) break;
if (i === j - 1) {
result = current[path];
break;
}
current = current[path];
}
return result;
};
const isObject = function(obj) {
return obj !== null && typeof obj === 'object';
};

View File

@ -1,6 +1,6 @@
{
"name": "element-theme-default",
"version": "1.3.7",
"version": "1.4.0-beta.1",
"description": "Element component default theme.",
"main": "lib/index.css",
"style": "lib/index.css",

View File

@ -68,9 +68,25 @@
transform: scaleY(0);
}
.el-zoom-in-left-enter-active,
.el-zoom-in-left-leave-active {
opacity: 1;
transform: scale(1, 1);
transition: var(--md-fade-transition);
transform-origin: top left;
}
.el-zoom-in-left-enter,
.el-zoom-in-left-leave-active {
opacity: 0;
transform: scale(.45, .45);
}
.collapse-transition {
transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out;
}
.horizontal-collapse-transition {
transition: 0.3s width ease-in-out, 0.3s padding-left ease-in-out, 0.3s padding-right ease-in-out;
}
.el-list-enter-active,
.el-list-leave-active {
@ -79,4 +95,8 @@
.el-list-enter, .el-list-leave-active {
opacity: 0;
transform: translateY(-30px);
}
.el-opacity-transition {
transition: opacity .3s cubic-bezier(.55,0,.1,1);
}

View File

@ -23,7 +23,7 @@
padding-left: 0;
background-color: var(--menu-item-fill);
@utils-clearfix;
& li {
list-style: none;
}
@ -137,6 +137,45 @@
}
}
}
@m collapse {
width: 64px;
> .el-menu-item,
> .el-submenu > .el-submenu__title {
text-align: center;
[class^="el-icon-"] {
margin: 0;
vertical-align: middle;
}
.el-submenu__icon-arrow {
display: none;
}
span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
}
.el-submenu {
position: relative;
& .el-menu {
position: absolute;
margin-left: 5px;
top: 0;
left: 100%;
z-index: 10;
}
&.is-opened {
> .el-submenu__title .el-submenu__icon-arrow {
transform: none;
}
}
}
}
}
@b menu-item {
@extend menu-item;
@ -175,6 +214,7 @@
height: 50px;
line-height: 50px;
padding: 0 45px;
min-width: 200px;
&:hover {
background-color: var(--color-base-gray);

View File

@ -80,9 +80,12 @@ export default {
if (!vnode) return vnode;
const data = vnode.data = vnode.data || {};
const on = vnode.data.on = vnode.data.on || {};
const nativeOn = vnode.data.nativeOn = vnode.data.nativeOn || {};
on.mouseenter = this.addEventHandle(on.mouseenter, () => { this.setExpectedState(true); this.handleShowPopper(); });
on.mouseleave = this.addEventHandle(on.mouseleave, () => { this.setExpectedState(false); this.debounceClose(); });
nativeOn.mouseenter = this.addEventHandle(nativeOn.mouseenter, () => { this.setExpectedState(true); this.handleShowPopper(); });
nativeOn.mouseleave = this.addEventHandle(nativeOn.mouseleave, () => { this.setExpectedState(false); this.debounceClose(); });
data.staticClass = this.concatClass(data.staticClass, 'el-tooltip');
return vnode;

View File

@ -1,28 +1,44 @@
import objectAssign from 'element-ui/src/utils/merge';
import { markNodeData, NODE_KEY } from './util';
const reInitChecked = function(node) {
const siblings = node.childNodes;
export const getChildState = node => {
let all = true;
let none = true;
for (let i = 0, j = siblings.length; i < j; i++) {
const sibling = siblings[i];
if (sibling.checked !== true || sibling.indeterminate) {
let allWithoutDisable = true;
for (let i = 0, j = node.length; i < j; i++) {
const n = node[i];
if (n.checked !== true || n.indeterminate) {
all = false;
if (!n.disabled) {
allWithoutDisable = false;
}
}
if (sibling.checked !== false || sibling.indeterminate) {
if (n.checked !== false || n.indeterminate) {
none = false;
}
}
return { all, none, allWithoutDisable, half: !all && !none };
};
const reInitChecked = function(node) {
const {all, none, half} = getChildState(node.childNodes);
if (all) {
node.setChecked(true);
} else if (!all && !none) {
node.setChecked('half');
node.checked = true;
node.indeterminate = false;
} else if (half) {
node.checked = false;
node.indeterminate = true;
} else if (none) {
node.setChecked(false);
node.checked = false;
node.indeterminate = false;
}
const parent = node.parent;
if (!parent || parent.level === 0) return;
if (!node.store.checkStrictly) {
reInitChecked(parent);
}
};
@ -145,6 +161,10 @@ export default class Node {
return null;
}
get disabled() {
return getPropertyFromData(this, 'disabled');
}
insertChild(child, index) {
if (!child) throw new Error('insertChild error: child is required.');
@ -260,16 +280,29 @@ export default class Node {
this.isLeaf = false;
}
setChecked(value, deep) {
setChecked(value, deep, recursion, passValue) {
this.indeterminate = value === 'half';
this.checked = value === true;
let { allWithoutDisable } = getChildState(this.childNodes);
if (this.childNodes.length && allWithoutDisable) {
this.checked = false;
value = false;
}
const handleDescendants = () => {
if (deep) {
const childNodes = this.childNodes;
for (let i = 0, j = childNodes.length; i < j; i++) {
const child = childNodes[i];
child.setChecked(value !== false, deep);
passValue = passValue || value !== false;
const isCheck = child.disabled ? child.checked : passValue;
child.setChecked(isCheck, deep, true, passValue);
}
const { half, all } = getChildState(childNodes);
if (!all) {
this.checked = all;
this.indeterminate = half;
}
}
};
@ -288,7 +321,7 @@ export default class Node {
const parent = this.parent;
if (!parent || parent.level === 0) return;
if (!this.store.checkStrictly) {
if (!this.store.checkStrictly && !recursion) {
reInitChecked(parent);
}
}
@ -337,7 +370,7 @@ export default class Node {
}
loadData(callback, defaultProps = {}) {
if (this.store.lazy === true && this.store.load && !this.loaded && !this.loading) {
if (this.store.lazy === true && this.store.load && !this.loaded && (!this.loading || Object.keys(defaultProps).length)) {
this.loading = true;
const resolve = (children) => {

View File

@ -188,61 +188,47 @@ export default class TreeStore {
}
_setCheckedKeys(key, leafOnly = false, checkedKeys) {
const allNodes = this._getAllNodes();
allNodes.sort((a, b) => b.level - a.level);
const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level);
const cache = Object.create(null);
const keys = Object.keys(checkedKeys);
allNodes.forEach((node) => {
let checked = keys.indexOf(node.data[key] + '') > -1;
if (!node.isLeaf) {
if (!this.checkStrictly) {
const childNodes = node.childNodes;
let all = true;
let none = true;
for (let i = 0, j = childNodes.length; i < j; i++) {
const child = childNodes[i];
if (child.checked !== true || child.indeterminate) {
all = false;
}
if (child.checked !== false || child.indeterminate) {
none = false;
}
}
if (all) {
node.setChecked(true, !this.checkStrictly);
} else if (!all && !none) {
checked = checked ? true : 'half';
node.setChecked(checked, !this.checkStrictly && checked === true);
} else if (none) {
node.setChecked(checked, !this.checkStrictly);
}
} else {
node.setChecked(checked, false);
}
if (leafOnly) {
allNodes.forEach(node => node.setChecked(false, false));
for (let i = 0, j = allNodes.length; i < j; i++) {
const node = allNodes[i];
const nodeKey = node.data[key].toString();
let checked = keys.indexOf(nodeKey) > -1;
if (!checked) {
if (node.checked && !cache[nodeKey]) {
node.setChecked(false, false);
const traverse = function(node) {
const childNodes = node.childNodes;
childNodes.forEach((child) => {
if (!child.isLeaf) {
child.setChecked(false, false);
}
traverse(child);
});
};
traverse(node);
}
} else {
node.setChecked(checked, false);
continue;
}
});
let parent = node.parent;
while (parent && parent.level > 0) {
cache[parent.data[key]] = true;
parent = parent.parent;
}
if (node.isLeaf || this.checkStrictly) {
node.setChecked(true, false);
continue;
}
node.setChecked(true, true);
if (leafOnly) {
node.setChecked(false, false);
const traverse = function(node) {
const childNodes = node.childNodes;
childNodes.forEach((child) => {
if (!child.isLeaf) {
child.setChecked(false, false);
}
traverse(child);
});
};
traverse(node);
}
}
}
setCheckedNodes(array, leafOnly = false) {

View File

@ -18,8 +18,8 @@
v-if="showCheckbox"
v-model="node.checked"
:indeterminate="node.indeterminate"
@change="handleCheckChange"
@click.native.stop="handleUserClick">
:disabled="!!node.disabled"
@change="handleCheckChange">
</el-checkbox>
<span
v-if="node.loading"
@ -155,16 +155,8 @@
}
},
handleUserClick() {
if (this.node.indeterminate) {
this.node.setChecked(this.node.checked, !this.tree.checkStrictly);
}
},
handleCheckChange(ev) {
if (!this.node.indeterminate) {
this.node.setChecked(ev.target.checked, !this.tree.checkStrictly);
}
this.node.setChecked(ev.target.checked, !this.tree.checkStrictly);
},
handleChildNodeExpand(nodeData, node, instance) {

View File

@ -69,7 +69,8 @@
return {
children: 'children',
label: 'label',
icon: 'icon'
icon: 'icon',
disabled: 'disabled'
};
}
},

View File

@ -158,7 +158,7 @@ if (typeof window !== 'undefined' && window.Vue) {
};
module.exports = {
version: '1.3.7',
version: '1.4.0-beta.1',
locale: locale.use,
i18n: locale.i18n,
install,

View File

@ -0,0 +1,21 @@
import Vue from 'vue';
export default function scrollIntoView(container, selected) {
if (Vue.prototype.$isServer) return;
if (!selected) {
container.scrollTop = 0;
return;
}
const top = selected.offsetTop;
const bottom = selected.offsetTop + selected.offsetHeight;
const viewRectTop = container.scrollTop;
const viewRectBottom = viewRectTop + container.clientHeight;
if (top < viewRectTop) {
container.scrollTop = top;
} else if (bottom > viewRectBottom) {
container.scrollTop = bottom - container.clientHeight;
}
}

View File

@ -19,3 +19,21 @@ export function toObject(arr) {
}
return res;
};
export const getValueByPath = function(object, prop) {
prop = prop || '';
const paths = prop.split('.');
let current = object;
let result = null;
for (let i = 0, j = paths.length; i < j; i++) {
const path = paths[i];
if (!current) break;
if (i === j - 1) {
result = current[path];
break;
}
current = current[path];
}
return result;
};

View File

@ -113,6 +113,7 @@ describe('Select', () => {
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-select>
@ -147,6 +148,7 @@ describe('Select', () => {
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
<p>{{item.label}} {{item.value}}</p>
</el-option>
@ -226,6 +228,7 @@ describe('Select', () => {
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-select>
@ -285,6 +288,44 @@ describe('Select', () => {
}, 100);
});
it('object typed value', done => {
vm = createVue({
template: `
<div>
<el-select v-model="value" value-key="id">
<el-option
v-for="item in options"
:label="item.label"
:key="item.id"
:value="item">
</el-option>
</el-select>
</div>
`,
data() {
return {
options: [{
id: 1,
label: 'label1'
}, {
id: 2,
label: 'label2'
}],
value: {
id: 1,
label: 'label1'
}
};
}
}, true);
setTimeout(() => {
expect(vm.$el.querySelector('.el-input__inner').value).to.equal('label1');
expect(vm.$el.querySelector('.el-select-dropdown__item').classList.contains('selected'));
done();
}, 100);
});
it('custom el-option template', () => {
vm = createVue({
template: `
@ -293,6 +334,7 @@ describe('Select', () => {
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
<p>{{item.label}} {{item.value}}</p>
</el-option>
@ -320,11 +362,13 @@ describe('Select', () => {
<el-select v-model="value">
<el-option-group
v-for="group in options"
:key="group.label"
:disabled="group.disabled"
:label="group.label">
<el-option
v-for="item in group.options"
:label="item.label"
:key="item.value"
:value="item.value">
</el-option>
</el-option-group>
@ -416,6 +460,7 @@ describe('Select', () => {
<el-option
v-for="item in options"
:label="item"
:key="item.value"
:value="item"
/>
</el-select>
@ -504,6 +549,7 @@ describe('Select', () => {
<el-option
v-for="item in options"
:label="item.label"
:key="item.value"
:value="item.value">
<p>{{item.label}} {{item.value}}</p>
</el-option>

View File

@ -61,6 +61,61 @@ describe('Tree', () => {
}, options), true);
};
const getDisableTreeVm = (props, options) => {
return createVue(Object.assign({
template: `
<el-tree ref="tree" :data="data" ${ props }></el-tree>
`,
data() {
return {
defaultExpandedKeys: [],
defaultCheckedKeys: [],
clickedNode: null,
count: 1,
data: [{
id: 1,
label: '一级 1',
children: [{
id: 11,
label: '二级 1-1',
children: [{
id: 111,
label: '三级 1-1',
disabled: true
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 21,
label: '二级 2-1'
}, {
id: 22,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 31,
label: '二级 3-1'
}, {
id: 32,
label: '二级 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label',
disabled: 'disabled'
}
};
}
}, options), true);
};
const ALL_NODE_COUNT = 9;
it('create', () => {
@ -344,6 +399,16 @@ describe('Tree', () => {
}, 0);
});
it('set disabled checkbox', done => {
vm = getDisableTreeVm(':props="defaultProps" show-checkbox node-key="id"');
const node = document.querySelectorAll('.el-tree-node__content')[2];
const nodeCheckbox = node.querySelector('.el-checkbox input');
vm.$nextTick(() => {
expect(nodeCheckbox.disabled).to.equal(true);
done();
});
});
it('check strictly', (done) => {
vm = getTreeVm(':props="defaultProps" show-checkbox check-strictly');
const tree = vm.$children[0];