mirror of https://github.com/ElemeFE/element
Merge branch 'dev' into 1.1
commit
d2f02b828f
|
@ -1,5 +1,22 @@
|
|||
## Changelog
|
||||
|
||||
### 1.0.9
|
||||
|
||||
*2016-12-27*
|
||||
|
||||
- Fixed DatePicker incorrectly triggering input event, #1834
|
||||
- Fixed Tree reporting `event is undefined` error in Firefox, #1945
|
||||
- Added `change` event for DatePicker, whose parameter is the formatted value, #1841
|
||||
- Added `header-align` attribute for Table, #1424
|
||||
- Fixed single select Table's highlight style not removing when data is removed, #1890
|
||||
- Fixed filterable Select lagging issue with more options, #1933
|
||||
- Fixed multiple disabled Select not disabling removing selected options issue, #2001
|
||||
- Fixed Col style not working in `xs`, #2011
|
||||
- Added `value` attribute for Tab, #2008
|
||||
- Fixed InputNumber `change` event incorrectly firing multiple times in some conditions, #1999
|
||||
- Added `clearable` attribute for DatePicker, #1994
|
||||
- Fixed Form always passing validation in async mode, #1936
|
||||
|
||||
### 1.0.8
|
||||
|
||||
*2016-12-20*
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
## 更新日志
|
||||
|
||||
### 1.0.9
|
||||
*2016-12-27*
|
||||
|
||||
- 修复 DatePicker 不能正确触发 input 事件的问题,现在只有当日期改变时才触发,#1834
|
||||
- 修复 Tree 在 Firefox 下会提示 event is undefined 的问题,#1945
|
||||
- 新增 DatePicker 的 `change` 事件,返回和输入框一致的格式化后的值,#1841
|
||||
- 新增 Table 的 `header-align` 属性,#1424
|
||||
- 修复单选的 Table 在数据移除时,高亮状态仍然存在的问题,#1890
|
||||
- 修复可搜索的 Select 在选项较多时的卡顿问题,#1933
|
||||
- 修复多选的 Select 在禁用状态下仍然能够手动删除选中项的问题,#2001
|
||||
- 修复 Col `xs` 分辨率下样式无效的问题,#2011
|
||||
- 新增 Tab 组件的 `value` 属性并支持 `v-model` 用法,#2008
|
||||
- 修复 Input Number 在某些条件下 change 事件被触发多次的问题,#1999
|
||||
- 新增 DatePicker 的 `clearable` 属性,#1994
|
||||
- 修复 Form 异步验证时某些条件下总是验证通过的问题,#1936
|
||||
|
||||
### 1.0.8
|
||||
*2016-12-20*
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
var cooking = require('cooking');
|
||||
var config = require('./config');
|
||||
var md = require('markdown-it')();
|
||||
var CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
var striptags = require('./strip-tags');
|
||||
var slugify = require('transliteration').slugify;
|
||||
var isProd = process.env.NODE_ENV === 'production';
|
||||
|
@ -113,5 +114,8 @@ if (isProd) {
|
|||
cooking.add('externals.vue-router', 'VueRouter');
|
||||
}
|
||||
|
||||
cooking.add('plugin.CopyWebpackPlugin', new CopyWebpackPlugin([
|
||||
{ from: 'examples/versions.json' }
|
||||
]));
|
||||
cooking.add('vue.preserveWhitespace', false);
|
||||
module.exports = cooking.resolve();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-main">
|
||||
<p class="footer-main-title">Element 1.0 Hydrogen</p>
|
||||
<p class="footer-main-title">Element {{ version }} Hydrogen</p>
|
||||
<a href="https://github.com/ElemeFE/element/issues" class="footer-main-link" target="_blank">{{ langConfig.feedback }}</a>
|
||||
<a href="https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.md" class="footer-main-link" target="_blank">{{ langConfig.contribution }}</a>
|
||||
</div>
|
||||
|
@ -134,8 +134,15 @@
|
|||
|
||||
<script type="text/babel">
|
||||
import compoLang from '../i18n/component.json';
|
||||
import { version } from 'main/index.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
version
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.path.split('/')[1];
|
||||
|
|
|
@ -12,6 +12,41 @@
|
|||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nav-dropdown {
|
||||
margin-bottom: 6px;
|
||||
width: 100%;
|
||||
span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
color: #5e6d82;
|
||||
line-height: 40px;
|
||||
transition: .2s;
|
||||
border-bottom: 1px solid #eaeefb;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
i {
|
||||
transition: .2s;
|
||||
font-size: 12px;
|
||||
color: #d3dce6;
|
||||
}
|
||||
@when active {
|
||||
span, i {
|
||||
color: #20a0ff;
|
||||
}
|
||||
i {
|
||||
transform: rotateZ(180deg) translateY(2px);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
span, i {
|
||||
color: #20a0ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
a {
|
||||
|
@ -53,9 +88,37 @@
|
|||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
.nav-dropdown-list {
|
||||
width: 120px;
|
||||
margin-top: -8px;
|
||||
li {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="side-nav" :style="navStyle">
|
||||
<el-dropdown
|
||||
v-show="isComponentPage"
|
||||
trigger="click"
|
||||
class="nav-dropdown"
|
||||
:class="{ 'is-active': dropdownVisible }">
|
||||
<span>
|
||||
{{ langConfig.dropdown }}{{ version }}
|
||||
<i class="el-icon-caret-bottom el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu
|
||||
slot="dropdown"
|
||||
:offset="-80"
|
||||
class="nav-dropdown-list"
|
||||
@input="handleDropdownToggle">
|
||||
<el-dropdown-item
|
||||
v-for="item in Object.keys(versions)"
|
||||
@click.native="switchVersion(item)">
|
||||
{{ item }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<ul>
|
||||
<li class="nav-item" v-for="item in data">
|
||||
<a v-if="!item.path" @click="expandMenu">{{item.name}}</a>
|
||||
|
@ -99,6 +162,9 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import compoLang from '../i18n/component.json';
|
||||
import { version } from 'main/index.js';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
data: Array,
|
||||
|
@ -111,7 +177,10 @@
|
|||
return {
|
||||
highlights: [],
|
||||
navState: [],
|
||||
isSmallScreen: false
|
||||
isSmallScreen: false,
|
||||
versions: [],
|
||||
version,
|
||||
dropdownVisible: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -122,9 +191,19 @@
|
|||
computed: {
|
||||
navStyle() {
|
||||
return this.isSmallScreen ? { 'padding-bottom': '60px' } : {};
|
||||
},
|
||||
isComponentPage() {
|
||||
return /^component-/.test(this.$route.name);
|
||||
},
|
||||
langConfig() {
|
||||
return compoLang.filter(config => config.lang === this.$route.meta.lang)[0]['nav'];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
switchVersion(version) {
|
||||
if (version === this.version) return;
|
||||
location.href = `${ location.origin }/${ this.versions[version] }/${ location.hash } `;
|
||||
},
|
||||
handleResize() {
|
||||
this.isSmallScreen = document.documentElement.clientWidth < 768;
|
||||
this.handlePathChange();
|
||||
|
@ -160,8 +239,21 @@
|
|||
if (!target.nextElementSibling || target.nextElementSibling.tagName !== 'UL') return;
|
||||
this.hideAllMenu();
|
||||
event.currentTarget.nextElementSibling.style.height = 'auto';
|
||||
},
|
||||
handleDropdownToggle(visible) {
|
||||
this.dropdownVisible = visible;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = _ => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
this.versions = JSON.parse(xhr.responseText);
|
||||
}
|
||||
};
|
||||
xhr.open('GET', '/versions.json');
|
||||
xhr.send();
|
||||
},
|
||||
mounted() {
|
||||
this.handleResize();
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
|
|
|
@ -51,7 +51,7 @@ Just edit `element-variables.css`, e.g. changing the theme color to red:
|
|||
```
|
||||
|
||||
### Build theme
|
||||
After saving the variable file, use `et` to build your theme. You can activate `watch` mode by adding a parameter `-w`:
|
||||
After saving the variable file, use `et` to build your theme. You can activate `watch` mode by adding a parameter `-w`. And if you customized the variable file's output, you need to add a parameter `-c` and variable file's name:
|
||||
```shell
|
||||
et
|
||||
|
||||
|
|
|
@ -256,6 +256,7 @@ Picking a date range is supported.
|
|||
| disabled | whether DatePicker is disabled | boolean | - | false |
|
||||
|size | size of Input | string | large/small/mini | — |
|
||||
| editable | whether the input is editable | boolean | - | true |
|
||||
| clearable | Whether to show clear button | boolean | - | true |
|
||||
| placeholder | placeholder | string | — | — |
|
||||
| type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |
|
||||
| format | format of the picker | string | year `yyyy` month `MM` day `dd`, hour `HH`, minute `mm`, second `ss` | yyyy-MM-dd |
|
||||
|
@ -274,4 +275,10 @@ Picking a date range is supported.
|
|||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| text | title of the shortcut | string | — | — |
|
||||
| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — |
|
||||
| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — |
|
||||
|
||||
|
||||
### Events
|
||||
| Event Name | Description | Parameters |
|
||||
|---------|--------|---------|
|
||||
| change | triggers when input value changes | formatted value |
|
||||
|
|
|
@ -210,6 +210,7 @@ Select date and time in one picker.
|
|||
| readonly | whether DatePicker is read only | boolean | — | false |
|
||||
| disabled | whether DatePicker is disabled | boolean | - | false |
|
||||
| editable | whether the input is editable | boolean | - | true |
|
||||
| clearable | Whether to show clear button | boolean | - | true |
|
||||
|size | size of Input | string | large/small/mini | — |
|
||||
| placeholder | placeholder | string | — | — |
|
||||
| type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |
|
||||
|
@ -229,3 +230,10 @@ Select date and time in one picker.
|
|||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| text | title of the shortcut | string | — | — |
|
||||
| onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — |
|
||||
|
||||
|
||||
### Events
|
||||
| Event Name | Description | Parameters |
|
||||
|---------|--------|---------|
|
||||
| change | triggers when input value changes | formatted value |
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
methods: {
|
||||
handleClick() {
|
||||
alert('button click');
|
||||
},
|
||||
handleCommand(command) {
|
||||
this.$message('click on item ' + command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,6 +129,36 @@ Use `hide-on-click` to define if menu closes on clicking.
|
|||
```
|
||||
:::
|
||||
|
||||
### Command event
|
||||
|
||||
Clicking each dropdown item fires an event whose parameter is assigned by each item.
|
||||
|
||||
:::demo
|
||||
```html
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
Dropdown List<i class="el-icon-caret-bottom el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="a">Action 1</el-dropdown-item>
|
||||
<el-dropdown-item command="b">Action 2</el-dropdown-item>
|
||||
<el-dropdown-item command="c">Action 3</el-dropdown-item>
|
||||
<el-dropdown-item command="d" disabled>Action 4</el-dropdown-item>
|
||||
<el-dropdown-item command="e" divided>Action 5</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleCommand(command) {
|
||||
this.$message('click on item ' + command);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
### Dropdown Attributes
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|
|
|
@ -591,7 +591,10 @@ Search data from server-side.
|
|||
|
||||
| Event Name | Description | Parameters |
|
||||
|----| ----| ----|
|
||||
|click | triggers when the icon inside Input is clicked | event object |
|
||||
|click | triggers when the icon inside Input is clicked | (event: Event) |
|
||||
| blur | triggers when the icon inside Input is blur | (event: Event) |
|
||||
| focus | triggers when the icon inside Input is focus | (event: Event) |
|
||||
| change | triggers when the icon inside Input value change | (value: string \| number) |
|
||||
|
||||
### Autocomplete Attributes
|
||||
|
||||
|
|
|
@ -1346,6 +1346,94 @@ Customize table column so it can be integrated with other components.
|
|||
```
|
||||
:::
|
||||
|
||||
### Expandable row
|
||||
|
||||
When the row content is too long and you do not want to display the horizontal scroll bar, you can use the expandable row feature.
|
||||
:::demo Activate expandable row by adding type="expand" and `inline-template` attribute,The template for `el-table-column` will be rendered as the contents of the expanded row, you can access the same attributes as the` inline-template`。
|
||||
```html
|
||||
<template>
|
||||
<el-table
|
||||
:data="tableData3"
|
||||
style="width: 100%">
|
||||
<el-table-column type="expand" inline-template>
|
||||
<div>
|
||||
<p>State: {{ row.state }}</p>
|
||||
<p>City: {{ row.city }}</p>
|
||||
<p>Address: {{ row.address }}</p>
|
||||
<p>Zip: {{ row.zip }}</p>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Date"
|
||||
prop="date">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="Name"
|
||||
prop="name">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData3: [{
|
||||
date: '2016-05-03',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}, {
|
||||
date: '2016-05-02',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}, {
|
||||
date: '2016-05-04',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}, {
|
||||
date: '2016-05-01',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}, {
|
||||
date: '2016-05-08',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}, {
|
||||
date: '2016-05-06',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}, {
|
||||
date: '2016-05-07',
|
||||
name: 'Tom',
|
||||
state: 'California',
|
||||
city: 'Los Angeles',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
zip: 'CA 90036'
|
||||
}]
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### Table Attributes
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
|
@ -1361,7 +1449,9 @@ Customize table column so it can be integrated with other components.
|
|||
| row-style | function that returns custom style for a row, or a string assigning custom style for every row | Function(row, index)/Object | — | — |
|
||||
| row-key | key of row data, used for optimizing rendering. Required if `reserve-selection` is on | Function(row)/String | — | — |
|
||||
| context | context of Table, e.g. `_self` refers to the current context, `$parent` parent context, `$root` root context, can be overridden by `context` in `el-table-column` | Object | - | current context where Table lies |
|
||||
| empty-text | Displayed text when data is empty. You can customize this area with `slot="empty"` | String | | - | No Data |
|
||||
| empty-text | Displayed text when data is empty. You can customize this area with `slot="empty"` | String | - | No Data |
|
||||
| default-expand-all | whether expand all rows by default, only works when the table has a column type="expand" | Boolean | - | false |
|
||||
| expand-row-keys | set expanded rows by this prop, prop's value is the keys of expand rows, you should set row-key before using this prop | Array | - | |
|
||||
| virtual-scrollbar | Enable virtual scrollbar | Boolean | - | false |
|
||||
|
||||
### Table Events
|
||||
|
@ -1380,6 +1470,7 @@ Customize table column so it can be integrated with other components.
|
|||
| sort-change | triggers when Table's sorting changes | { column, prop, order } |
|
||||
| filter-change | column's key. If you need to use the filter-change event, this attribute is mandatory to identify which column is being filtered | filters |
|
||||
| current-change | triggers when current row changes | currentRow, oldCurrentRow |
|
||||
| expand | triggers when user expands or collapses a row | row, expanded |
|
||||
|
||||
### Table Methods
|
||||
| Method | Description | Parameters |
|
||||
|
@ -1390,7 +1481,7 @@ Customize table column so it can be integrated with other components.
|
|||
### Table-column Attributes
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| type | type of the column. If set to `selection`, the column will display checkbox. If set to `index`, the column will display index of the row (staring from 1) | string | selection/index | — |
|
||||
| type | type of the column. If set to `selection`, the column will display checkbox. If set to `index`, the column will display index of the row (staring from 1). If set to `expand`, the column will display expand icon. | string | selection/index/expand | — |
|
||||
| label | column label | string | — | — |
|
||||
| column-key | column's key. If you need to use the filter-change event, you need this attribute to identify which column is being filtered | string | string | - | - |
|
||||
| prop | field name. You can also use its alias: `property` | string | — | — |
|
||||
|
@ -1404,6 +1495,7 @@ Customize table column so it can be integrated with other components.
|
|||
| formatter | function that formats content | Function(row, column) | — | — |
|
||||
| show-overflow-tooltip | whether to hide extra content and show them in a tooltip when hovering on the cell | boolean | — | false |
|
||||
| align | alignment | string | left/center/right | left |
|
||||
| header-align | alignment of the table header. If omitted, the value of the above `align` attribute will be applied | String | left/center/right | — |
|
||||
| class-name | class name of cells in the column | string | — | — |
|
||||
| selectable | function that determines if a certain row can be selected, works when `type` is 'selection' | Function(row, index) | — | — |
|
||||
| reserve-selection | whether to reserve selection after data refreshing, works when `type` is 'selection' | boolean | — | false |
|
||||
|
|
|
@ -2,7 +2,18 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first'
|
||||
activeName: 'first',
|
||||
activeName2: 'first',
|
||||
tabs: [{
|
||||
title: 'Tab 1',
|
||||
name: '1',
|
||||
content: 'Tab 1 content'
|
||||
}, {
|
||||
title: 'Tab 2',
|
||||
name: '2',
|
||||
content: 'Tab 2 content'
|
||||
}],
|
||||
tabIndex: 2
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -11,6 +22,9 @@
|
|||
},
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
renderTab(h, tab) {
|
||||
return <span><i class="el-icon-date"></i> {tab.label}</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +38,11 @@ Divide data collections which are related yet belong to different types.
|
|||
|
||||
Basic and concise tabs.
|
||||
|
||||
:::demo Tabs provide a selective card functionality and it can be achieved by just using `el-tabs` and child element `el-tab-pane`. In these two elements, we provide a list of attributes. The `label` in `el-tab-pane` determines the label of selective cards, and you can write content in the label. In this example, we add a `active-name` attribute indicating the active card in `el-tabs`, which can take a `String` value. In the `el-tab-pane` you can set corresponding `name` attribute, and if there is no `name`, the default sequence is `1`/`2`/`3`/`4`. In this example, the selected card is card 2. If `name` is omitted, setting `active-name` to `2` can reach the same goal.
|
||||
:::demo Tabs provide a selective card functionality. By default the first tab is selected as active, and you can activate any tab by setting the `value` attribute.
|
||||
|
||||
```html
|
||||
<template>
|
||||
<el-tabs :active-name="activeName">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="User" name="first">User</el-tab-pane>
|
||||
<el-tab-pane label="Config" name="second">Config</el-tab-pane>
|
||||
<el-tab-pane label="Role" name="third">Role</el-tab-pane>
|
||||
|
@ -41,6 +55,11 @@ Basic and concise tabs.
|
|||
return {
|
||||
activeName: 'first'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -55,7 +74,7 @@ Tabs styled as cards.
|
|||
|
||||
```html
|
||||
<template>
|
||||
<el-tabs type="card" @tab-click="handleClick" @tab-remove="handleRemove">
|
||||
<el-tabs type="card" @tab-click="handleClick">
|
||||
<el-tab-pane label="User">User</el-tab-pane>
|
||||
<el-tab-pane label="Config">Config</el-tab-pane>
|
||||
<el-tab-pane label="Role">Role</el-tab-pane>
|
||||
|
@ -64,10 +83,12 @@ Tabs styled as cards.
|
|||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleRemove(tab) {
|
||||
console.log(tab);
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
}
|
||||
|
@ -81,7 +102,7 @@ Tabs styled as cards.
|
|||
|
||||
Closable tabs.
|
||||
|
||||
:::demo You can set `closable` attribute in `el-tabs`. It accept `Boolean` and Tab will be closable when the boolean is `true`.
|
||||
:::demo You can set the closable attribute in el-tabs to make all tabs closable. Also, closable can be set in a tab panel to make that specific tab closable.
|
||||
|
||||
```html
|
||||
<template>
|
||||
|
@ -125,12 +146,37 @@ Border card tabs.
|
|||
|
||||
:::
|
||||
|
||||
### Custom Tab
|
||||
|
||||
You can use `label-content` property to customize the tab
|
||||
|
||||
:::demo `label-content` is a render function,which return the vnode of the tab.
|
||||
```html
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="Route" :label-content="renderTab">Route</el-tab-pane>
|
||||
<el-tab-pane label="Config">Config</el-tab-pane>
|
||||
<el-tab-pane label="Role">Role</el-tab-pane>
|
||||
<el-tab-pane label="Task">Task</el-tab-pane>
|
||||
</el-tabs>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
renderTab(h, tab) {
|
||||
return <span><i class="el-icon-date"></i> {tab.label}</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### Tabs Attributes
|
||||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|---------- |-------- |---------- |------------- |-------- |
|
||||
| type | type of Tab | string | card/border-card | — |
|
||||
| closable | whether Tab is closable | boolean | — | false |
|
||||
| active-name | name of the selected tab | string | — | name of first tab |
|
||||
| active-name(deprecated) | name of the selected tab | string | — | name of first tab |
|
||||
| value | name of the selected tab | string | — | name of first tab |
|
||||
|
||||
### Tabs Events
|
||||
| Event Name | Description | Parameters |
|
||||
|
@ -145,3 +191,4 @@ Border card tabs.
|
|||
| label-content | render function for tab title | Function(h, tab:vueInstance) | - | - |
|
||||
| disabled | whether Tab is disabled | boolean | - | false |
|
||||
| name | identifier corresponding to the activeName of Tabs, representing the alias of the tab-pane | string | — | ordinal number of the tab-pane in the sequence, i.e. the first tab-pane is '1' |
|
||||
| closable | whether Tab is closable | boolean | — | false |
|
||||
|
|
|
@ -146,7 +146,8 @@ Can pick an arbitrary time range.
|
|||
| readonly | whether DatePicker is read only | boolean | — | false |
|
||||
| disabled | whether DatePicker is disabled | boolean | - | false |
|
||||
| editable | whether the input is editable | boolean | - | true |
|
||||
|size | size of Input | string | large/small/mini | — |
|
||||
| clearable | Whether to show clear button | boolean | - | true |
|
||||
| size | size of Input | string | large/small/mini | — |
|
||||
| placeholder | placeholder | string | — | — |
|
||||
| format | format of the picker | string | hour `HH`, minute `mm`, second `ss` | HH:mm:ss |
|
||||
| value | value of the picker | date for Time Picker, and string for Time Select | hour `HH`, minute `mm`, second `ss` | HH:mm:ss |
|
||||
|
@ -167,3 +168,10 @@ Can pick an arbitrary time range.
|
|||
| Attribute | Description | Type | Accepted Values | Default |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| selectableRange | available time range, e.g.`'18:30:00 - 20:30:00'`or`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string/array | — | — |
|
||||
|
||||
|
||||
### Events
|
||||
| Event Name | Description | Parameters |
|
||||
|---------|--------|---------|
|
||||
| change | triggers when input value changes | formatted value |
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ et -i [可以自定义变量文件]
|
|||
```
|
||||
|
||||
### 编译主题
|
||||
保存文件后,到命令行里执行 `et` 编译主题,如果你想启用 `watch` 模式,实时编译主题,增加 `-w` 参数。
|
||||
保存文件后,到命令行里执行 `et` 编译主题,如果你想启用 `watch` 模式,实时编译主题,增加 `-w` 参数;如果你在初始化时指定了自定义变量文件,则需要增加 `-c` 参数,并带上你的变量文件名
|
||||
```shell
|
||||
et
|
||||
|
||||
|
|
|
@ -289,6 +289,7 @@
|
|||
| readonly | 完全只读 | boolean | — | false |
|
||||
| disabled | 禁用 | boolean | - | false |
|
||||
| editable | 文本框可输入 | boolean | - | true |
|
||||
| clearable | 是否显示清除按钮 | boolean | - | true |
|
||||
| size | 输入框尺寸 | string | large, small, mini | — |
|
||||
| placeholder | 占位内容 | string | — | — |
|
||||
| type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |
|
||||
|
@ -309,3 +310,9 @@
|
|||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| text | 标题文本 | string | — | — |
|
||||
| onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | function | — | — |
|
||||
|
||||
### Events
|
||||
| Event Name | Description | Parameters |
|
||||
|---------|--------|---------|
|
||||
| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
|
||||
|
||||
|
|
|
@ -233,6 +233,7 @@
|
|||
| readonly | 完全只读 | boolean | — | false |
|
||||
| disabled | 禁用 | boolean | - | false |
|
||||
| editable | 文本框可输入 | boolean | - | true |
|
||||
| clearable | 是否显示清除按钮 | boolean | - | true |
|
||||
| size | 输入框尺寸 | string | large, small, mini | — |
|
||||
| placeholder | 占位内容 | string | — | — |
|
||||
| type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |
|
||||
|
@ -254,3 +255,9 @@
|
|||
| onClick | 选中后的回调函数,参数是 vm,可通过触发 'pick' 事件设置选择器的值。例如 vm.$emit('pick', new Date()) | function | — | — |
|
||||
|
||||
|
||||
### Events
|
||||
| Event Name | Description | Parameters |
|
||||
|---------|--------|---------|
|
||||
| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
methods: {
|
||||
handleClick() {
|
||||
alert('button click');
|
||||
},
|
||||
handleCommand(command) {
|
||||
this.$message('click on item ' + command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +171,35 @@
|
|||
```
|
||||
:::
|
||||
|
||||
### 指令事件
|
||||
|
||||
点击菜单项后会触发事件,用户可以通过相应的菜单项 key 进行不同的操作
|
||||
|
||||
:::demo
|
||||
```html
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
下拉菜单<i class="el-icon-caret-bottom el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="a">黄金糕</el-dropdown-item>
|
||||
<el-dropdown-item command="b">狮子头</el-dropdown-item>
|
||||
<el-dropdown-item command="c">螺蛳粉</el-dropdown-item>
|
||||
<el-dropdown-item command="d" disabled>双皮奶</el-dropdown-item>
|
||||
<el-dropdown-item command="e" divided>蚵仔煎</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleCommand(command) {
|
||||
this.$message('click on item ' + command);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### Dropdown Attributes
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|
|
|
@ -803,7 +803,7 @@
|
|||
|---------- |-------------- |
|
||||
| validate(cb) | 对整个表单进行校验的方法 |
|
||||
| validateField(prop, cb) | 对部分表单字段进行校验的方法 |
|
||||
| resetFields | 对整个表单进行重置,将所有字段值重置为空并移除校验结果 |
|
||||
| resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 |
|
||||
|
||||
### Form-Item Attributes
|
||||
|
||||
|
|
|
@ -203,9 +203,7 @@
|
|||
|
||||
::: demo
|
||||
```html
|
||||
<el-input
|
||||
placeholder="请输入内容"
|
||||
v-model="input">
|
||||
<el-input v-model="input" placeholder="请输入内容">
|
||||
</el-input>
|
||||
|
||||
<script>
|
||||
|
@ -759,9 +757,10 @@ export default {
|
|||
### Input Events
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
|---------|--------|---------|
|
||||
| click | 点击 Input 内的图标时触发 | event |
|
||||
| blur | 在 Input 失去焦点时触发 | event |
|
||||
| focus | 在 Input 或得焦点时触发 | event |
|
||||
| click | 点击 Input 内的图标时触发 | (event: Event) |
|
||||
| blur | 在 Input 失去焦点时触发 | (event: Event) |
|
||||
| focus | 在 Input 或得焦点时触发 | (event: Event) |
|
||||
| change | 在 Input 值改变时触发 | (value: string \| number) |
|
||||
|
||||
### Autocomplete Attributes
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-02',
|
||||
|
@ -67,6 +68,7 @@
|
|||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-04',
|
||||
|
@ -81,6 +83,7 @@
|
|||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-08',
|
||||
|
@ -88,6 +91,7 @@
|
|||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-06',
|
||||
|
@ -95,6 +99,7 @@
|
|||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-07',
|
||||
|
@ -102,6 +107,7 @@
|
|||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}],
|
||||
tableData4: [{
|
||||
|
@ -1354,6 +1360,74 @@
|
|||
```
|
||||
:::
|
||||
|
||||
### 展开行
|
||||
|
||||
当行内容过多并且不想显示横向滚动条时,可以使用 Table 展开行功能。
|
||||
:::demo 通过设置 type="expand" 和 `inline-template` 属性可以开启展开行功能,`el-table-column` 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用 `inline-template` 的时候相同。
|
||||
```html
|
||||
<template>
|
||||
<el-table
|
||||
:data="tableData3"
|
||||
style="width: 100%">
|
||||
<el-table-column type="expand" inline-template>
|
||||
<div>
|
||||
<p>省: {{ row.province }}</p>
|
||||
<p>市: {{ row.city }}</p>
|
||||
<p>住址: {{ row.detailAddress }}</p>
|
||||
<p>邮编: {{ row.zip }}</p>
|
||||
</div>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="日期"
|
||||
prop="date">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="姓名"
|
||||
prop="name">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData3: [{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}, {
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
detailAddress: '金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### Table Attributes
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
|
@ -1368,9 +1442,12 @@
|
|||
| row-style | 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style。 | Function(row, index)/Object | — | — |
|
||||
| row-key | 行数据的 Key,用来优化 Table 的渲染;在使用 reserve-selection 功能的情况下,该属性是必填的 | Function(row)/String | — | — |
|
||||
| context | 设置上下文环境,例如设置当前上下文就是 `_self`,父级就是 `$parent`,根组件 `$root`。优先读取 column 的 context 属性。 | Object | - | Table 所处上下文 |
|
||||
| empty-text | 空数据时显示的文本内容,也可以通过 `slot="empty"` 设置 | String | | - | 暂无数据 |
|
||||
| empty-text | 空数据时显示的文本内容,也可以通过 `slot="empty"` 设置 | String | - | 暂无数据 |
|
||||
| default-expand-all | 是否默认展开所有行,当 Table 中存在 type="expand" 的 Column 的时候有效 | Boolean | - | false |
|
||||
| expand-row-keys | 可以通过该属性设置 Table 目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。| Array | - | |
|
||||
| virtual-scrollbar | 启用虚拟滚动条 | Boolean | - | false |
|
||||
|
||||
|
||||
### Table Events
|
||||
| 事件名 | 说明 | 参数 |
|
||||
| ---- | ---- | ---- |
|
||||
|
@ -1387,6 +1464,7 @@
|
|||
| sort-change | 当表格的排序条件发生变化的时候会触发该事件 | { column, prop, order } |
|
||||
| filter-change | 当表格的筛选条件发生变化的时候会触发该事件,参数的值是一个对象,对象的 key 是 column 的 columnKey,对应的 value 为用户选择的筛选条件的数组。 | filters |
|
||||
| current-change | 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性 | currentRow, oldCurrentRow |
|
||||
| expand | 当用户对某一行展开或者关闭的上会触发该事件 | row, expanded |
|
||||
|
||||
### Table Methods
|
||||
| 方法名 | 说明 | 参数 |
|
||||
|
@ -1397,7 +1475,7 @@
|
|||
### Table-column Attributes
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| type | 对应列的类型。如果设置了 `selection` 则显示多选框,如果设置了 `index` 则显示该行的索引(从 1 开始计算) | string | selection/index | — |
|
||||
| type | 对应列的类型。如果设置了 `selection` 则显示多选框;如果设置了 `index` 则显示该行的索引(从 1 开始计算);如果设置了 expand 则显示为一个可展开的按钮 | string | selection/index/expand | — |
|
||||
| column-key | column 的 key,如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件 | string | - | - |
|
||||
| label | 显示的标题 | string | — | — |
|
||||
| prop | 对应列内容的字段名,也可以使用 property 属性 | string | — | — |
|
||||
|
@ -1410,7 +1488,8 @@
|
|||
| resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true |
|
||||
| formatter | 用来格式化内容 | Function(row, column) | — | — |
|
||||
| show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | Boolean | — | false |
|
||||
| align | 对齐方式 | String | left, center, right | left |
|
||||
| align | 对齐方式 | String | left/center/right | left |
|
||||
| header-align | 表头对齐方式,若不设置该项,则使用表格的对齐方式 | String | left/center/right | — |
|
||||
| class-name | 列的 className | string | — | — |
|
||||
| selectable | 仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选 | Function(row, index) | — | — |
|
||||
| reserve-selection | 仅对 type=selection 的列有效,类型为 Boolean,为 true 则代表会保留之前数据的选项,需要配合 Table 的 clearSelection 方法使用。 | Boolean | — | false |
|
||||
|
|
|
@ -2,7 +2,18 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first'
|
||||
activeName: 'first',
|
||||
activeName2: 'first',
|
||||
tabs: [{
|
||||
title: 'Tab 1',
|
||||
name: '1',
|
||||
content: 'Tab 1 content'
|
||||
}, {
|
||||
title: 'Tab 2',
|
||||
name: '2',
|
||||
content: 'Tab 2 content'
|
||||
}],
|
||||
tabIndex: 2
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -11,22 +22,27 @@
|
|||
},
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
renderTab(h, tab) {
|
||||
return <span><i class="el-icon-date"></i> {tab.label}</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
## Tabs 标签页
|
||||
|
||||
分隔内容上有关联但属于不同类别的数据集合。
|
||||
|
||||
### 基础用法
|
||||
|
||||
基础的、简洁的标签页。
|
||||
|
||||
:::demo Tabs 组件提供了选项卡功能,只需要使用`el-tabs`和子元素`el-tab-pane`即可,在两个元素中,我们分别提供了一系列的属性来方便使用,`el-tab-pane`中`label`决定了选项卡标题,标签内部写入内容即可。在下例中我们在`el-tabs`中设置了`active-name`属性,接受一个`String`值,表明选中的选项卡,在`el-tab-pane`中可以设置对应的`name`属性,如果没有设置`name`,则默认值为顺序的`1`/`2`/`3`/`4`。例子选中选项卡2,如果不设置`name`,将`active-name`设为`2`,可以达成相同效果。
|
||||
:::demo Tabs 组件提供了选项卡功能,默认选中第一个标签页,你也可以通过 `value` 属性来指定当前选中的标签页。
|
||||
|
||||
```html
|
||||
<template>
|
||||
<el-tabs :active-name="activeName">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
|
||||
<el-tab-pane label="配置管理" name="second">配置管理</el-tab-pane>
|
||||
<el-tab-pane label="角色管理" name="third">角色管理</el-tab-pane>
|
||||
|
@ -39,6 +55,11 @@
|
|||
return {
|
||||
activeName: 'first'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -49,23 +70,25 @@
|
|||
|
||||
选项卡样式的标签页。
|
||||
|
||||
:::demo 只需要设置`type`属性即可,如果需要标签风格,将其设置为`card`。
|
||||
:::demo 只需要设置 `type` 属性为 `card` 就可以使选项卡改变为标签风格。
|
||||
|
||||
```html
|
||||
<template>
|
||||
<el-tabs type="card" @tab-click="handleClick" @tab-remove="handleRemove">
|
||||
<el-tab-pane label="用户管理">用户管理</el-tab-pane>
|
||||
<el-tab-pane label="配置管理">配置管理</el-tab-pane>
|
||||
<el-tab-pane label="角色管理">角色管理</el-tab-pane>
|
||||
<el-tab-pane label="定时任务补偿">定时任务补偿</el-tab-pane>
|
||||
<el-tabs v-model="activeName2" type="card" @tab-click="handleClick">
|
||||
<el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
|
||||
<el-tab-pane label="配置管理" name="second">配置管理</el-tab-pane>
|
||||
<el-tab-pane label="角色管理" name="third">角色管理</el-tab-pane>
|
||||
<el-tab-pane label="定时任务补偿" name="fourth">定时任务补偿</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleRemove(tab) {
|
||||
console.log(tab);
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
}
|
||||
|
@ -79,11 +102,11 @@
|
|||
|
||||
可以关闭标签页。
|
||||
|
||||
:::demo 在`el-tabs`中设置`closable`属性,接受一个`Boolean`,设置为`true`时为可关闭。
|
||||
:::demo 通过设置 `closable` 属性来打开 `Tabs` 的可关闭标签效果, `closable` 也可以设置在 `Tab Panel` 中实现部分标签页的可关闭效果。
|
||||
|
||||
```html
|
||||
<template>
|
||||
<el-tabs type="card" :closable="true" @tab-click="handleClick" @tab-remove="handleRemove">
|
||||
<el-tabs type="card" closable @tab-click="handleClick" @tab-remove="handleRemove">
|
||||
<el-tab-pane label="用户管理">用户管理</el-tab-pane>
|
||||
<el-tab-pane label="配置管理">配置管理</el-tab-pane>
|
||||
<el-tab-pane label="角色管理">角色管理</el-tab-pane>
|
||||
|
@ -120,12 +143,52 @@
|
|||
```
|
||||
:::
|
||||
|
||||
### 自定义标签页
|
||||
|
||||
可以通过 `label-content` 属性来实现自定义标签页的内容
|
||||
|
||||
:::demo `label-content` 是一个 render function,在这个方法里返回的 vnode 会被渲染到标签页中。
|
||||
```html
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="我的行程" :label-content="renderTab">我的行程</el-tab-pane>
|
||||
<el-tab-pane label="消息中心">消息中心</el-tab-pane>
|
||||
<el-tab-pane label="角色管理">角色管理</el-tab-pane>
|
||||
<el-tab-pane label="定时任务补偿">定时任务补偿</el-tab-pane>
|
||||
</el-tabs>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
renderTab(h, tab) {
|
||||
return <span><i class="el-icon-date"></i> {tab.label}</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
:::
|
||||
|
||||
### 动态增加标签页
|
||||
|
||||
展示如何通过触发器来动态增加标签页
|
||||
|
||||
:::demo
|
||||
```html
|
||||
<div style="margin-bottom: 20px;">
|
||||
<el-button size="small" @click="tabs.push({ name: 'Tab ' + ++tabIndex, title: 'new Tab', content: 'new Tab content' })">add tab</el-button>
|
||||
</div>
|
||||
<el-tabs type="card" closable>
|
||||
<el-tab-pane v-for="(item, index) in tabs" :label="item.title" :name="item.name">{{item.content}}</el-tab-pane>
|
||||
</el-tabs>
|
||||
```
|
||||
:::
|
||||
|
||||
### Tabs Attributes
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|---------- |-------- |---------- |------------- |-------- |
|
||||
| type | 风格类型 | string | card/border-card | — |
|
||||
| closable | 标签是否可关闭 | boolean | — | false |
|
||||
| active-name | 选中选项卡的 name | string | — | 第一个选项卡的 name |
|
||||
| active-name(deprecated) | 选中选项卡的 name | string | — | 第一个选项卡的 name |
|
||||
| value | 绑定值,选中选项卡的 name | string | — | 第一个选项卡的 name |
|
||||
|
||||
### Tabs Events
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
|
@ -140,3 +203,4 @@
|
|||
| label-content | 选项卡的标题的渲染 Function | Function(h, tab:vueInstance) | - | - |
|
||||
| disabled | 是否禁用 | boolean | - | false |
|
||||
| name | 与选项卡 activeName 对应的标识符,表示选项卡别名 | string | — | 该选项卡在选项卡列表中的顺序值,如第一个选项卡则为'1' |
|
||||
| closable | 标签是否可关闭 | boolean | — | false |
|
||||
|
|
|
@ -153,6 +153,7 @@
|
|||
| readonly | 完全只读 | boolean | — | false |
|
||||
| disabled | 禁用 | boolean | - | false |
|
||||
| editable | 文本框可输入 | boolean | - | true |
|
||||
| clearable | 是否显示清除按钮 | boolean | - | true |
|
||||
| size | 输入框尺寸 | string | large, small, mini | — |
|
||||
| placeholder | 占位内容 | string | — | — |
|
||||
| format | 时间格式化(TimePicker) | string | 小时:`HH`,分:`mm`,秒:`ss` | 'HH:mm:ss' |
|
||||
|
@ -175,3 +176,11 @@
|
|||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||
| selectableRange | 可选时间段,例如`'18:30:00 - 20:30:00'`或者传入数组`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string/array | — | — |
|
||||
|
||||
|
||||
### Events
|
||||
| Event Name | Description | Parameters |
|
||||
|---------|--------|---------|
|
||||
| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value |
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
"guide": "指南",
|
||||
"components": "组件",
|
||||
"resource": "资源"
|
||||
},
|
||||
"nav": {
|
||||
"dropdown": "版本:"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -35,6 +38,9 @@
|
|||
"guide": "Guide",
|
||||
"components": "Component",
|
||||
"resource": "Resource"
|
||||
},
|
||||
"nav": {
|
||||
"dropdown": "Version: "
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"1.0.9": "1.0"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "element-ui",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.9",
|
||||
"description": "A Component Library for Vue.js.",
|
||||
"main": "lib/element-ui.common.js",
|
||||
"files": [
|
||||
|
@ -58,13 +58,14 @@
|
|||
"babel-loader": "^6.2.5",
|
||||
"babel-plugin-module-resolver": "^2.2.0",
|
||||
"babel-plugin-syntax-jsx": "^6.8.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.1.0",
|
||||
"babel-plugin-transform-vue-jsx": "^3.3.0",
|
||||
"babel-preset-es2015": "^6.14.0",
|
||||
"chai": "^3.5.0",
|
||||
"cheerio": "^0.18.0",
|
||||
"cooking": "^1.2.0",
|
||||
"cooking-lint": "^0.1.3",
|
||||
"cooking-vue2": "^0.3.0",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"coveralls": "^2.11.14",
|
||||
"cp-cli": "^1.0.2",
|
||||
"cross-env": "^3.1.3",
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<template>
|
||||
<label class="el-checkbox">
|
||||
<span class="el-checkbox__input">
|
||||
<span class="el-checkbox__inner"
|
||||
:class="{
|
||||
'is-disabled': disabled,
|
||||
'is-checked': isChecked,
|
||||
'is-indeterminate': indeterminate,
|
||||
'is-focus': focus
|
||||
}"
|
||||
></span>
|
||||
<span class="el-checkbox__input"
|
||||
:class="{
|
||||
'is-disabled': disabled,
|
||||
'is-checked': isChecked,
|
||||
'is-indeterminate': indeterminate,
|
||||
'is-focus': focus
|
||||
}"
|
||||
>
|
||||
<span class="el-checkbox__inner"></span>
|
||||
<input
|
||||
v-if="trueLabel || falseLabel"
|
||||
class="el-checkbox__original"
|
||||
|
|
|
@ -293,7 +293,7 @@
|
|||
handleClear() {
|
||||
this.minDate = null;
|
||||
this.maxDate = null;
|
||||
this.handleConfirm();
|
||||
this.handleConfirm(false);
|
||||
},
|
||||
|
||||
handleDateInput(event, type) {
|
||||
|
@ -376,10 +376,8 @@
|
|||
this.maxDate = val.maxDate;
|
||||
this.minDate = val.minDate;
|
||||
|
||||
if (!close) return;
|
||||
if (!this.showTime) {
|
||||
this.$emit('pick', [this.minDate, this.maxDate]);
|
||||
}
|
||||
if (!close || this.showTime) return;
|
||||
this.handleConfirm();
|
||||
},
|
||||
|
||||
changeToToday() {
|
||||
|
@ -456,7 +454,7 @@
|
|||
this.resetDate();
|
||||
},
|
||||
|
||||
handleConfirm(visible) {
|
||||
handleConfirm(visible = false) {
|
||||
this.$emit('pick', [this.minDate, this.maxDate], visible);
|
||||
},
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@
|
|||
methods: {
|
||||
handleClear() {
|
||||
this.date = new Date();
|
||||
this.$emit('pick', '');
|
||||
this.$emit('pick');
|
||||
},
|
||||
|
||||
resetDate() {
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
},
|
||||
|
||||
handleClear() {
|
||||
this.$emit('pick', '');
|
||||
this.$emit('pick');
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
|
||||
methods: {
|
||||
handleClear() {
|
||||
this.$emit('pick', '');
|
||||
this.$emit('pick');
|
||||
},
|
||||
|
||||
handleCancel() {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<script>
|
||||
import Vue from 'vue';
|
||||
import Clickoutside from 'element-ui/src/utils/clickoutside';
|
||||
import { formatDate, parseDate, getWeekNumber } from './util';
|
||||
import { formatDate, parseDate, getWeekNumber, equalDate } from './util';
|
||||
import Popper from 'element-ui/src/utils/vue-popper';
|
||||
import Emitter from 'element-ui/src/mixins/emitter';
|
||||
import ElInput from 'element-ui/packages/input';
|
||||
|
@ -187,6 +187,10 @@ export default {
|
|||
readonly: Boolean,
|
||||
placeholder: String,
|
||||
disabled: Boolean,
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
popperClass: String,
|
||||
editable: {
|
||||
type: Boolean,
|
||||
|
@ -305,9 +309,10 @@ export default {
|
|||
if (parsedValue && this.picker) {
|
||||
this.picker.value = parsedValue;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
this.picker.value = value;
|
||||
}
|
||||
this.picker.value = value;
|
||||
this.$forceUpdate();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -324,21 +329,36 @@ export default {
|
|||
methods: {
|
||||
handleMouseEnterIcon() {
|
||||
if (this.readonly || this.disabled) return;
|
||||
if (!this.valueIsEmpty) {
|
||||
if (!this.valueIsEmpty && this.clearable) {
|
||||
this.showClose = true;
|
||||
}
|
||||
},
|
||||
|
||||
handleClickIcon() {
|
||||
if (this.readonly || this.disabled) return;
|
||||
if (this.valueIsEmpty) {
|
||||
this.pickerVisible = !this.pickerVisible;
|
||||
} else {
|
||||
if (this.showClose) {
|
||||
this.internalValue = '';
|
||||
this.$emit('input', '');
|
||||
} else {
|
||||
this.pickerVisible = !this.pickerVisible;
|
||||
}
|
||||
},
|
||||
|
||||
dateIsUpdated(date) {
|
||||
let updated = true;
|
||||
|
||||
if (Array.isArray(date)) {
|
||||
if (equalDate(this.cacheDateMin, date[0]) &&
|
||||
equalDate(this.cacheDateMax, date[1])) updated = false;
|
||||
this.cacheDateMin = date[0];
|
||||
this.cacheDateMax = date[1];
|
||||
} else {
|
||||
if (equalDate(this.cacheDate, date)) updated = false;
|
||||
this.cacheDate = date;
|
||||
}
|
||||
|
||||
return updated;
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.pickerVisible = false;
|
||||
},
|
||||
|
@ -419,7 +439,9 @@ export default {
|
|||
|
||||
this.picker.$on('dodestroy', this.doDestroy);
|
||||
this.picker.$on('pick', (date, visible = false) => {
|
||||
this.$emit('input', date);
|
||||
if (this.dateIsUpdated(date)) this.$emit('input', date);
|
||||
|
||||
this.$nextTick(() => this.$emit('change', this.visualValue));
|
||||
this.pickerVisible = this.picker.visible = visible;
|
||||
this.picker.resetView && this.picker.resetView();
|
||||
});
|
||||
|
|
|
@ -8,6 +8,10 @@ const newArray = function(start, end) {
|
|||
return result;
|
||||
};
|
||||
|
||||
export const equalDate = function(dateA, dateB) {
|
||||
return new Date(dateA).getTime() === new Date(dateB).getTime();
|
||||
};
|
||||
|
||||
export const toDate = function(date) {
|
||||
date = new Date(date);
|
||||
if (isNaN(date.getTime())) return null;
|
||||
|
|
|
@ -45,7 +45,7 @@ Vue.component('el-form-item', ElForm)
|
|||
|---------- |-------------- |
|
||||
| validate(cb) | 对整个表单进行校验的方法 |
|
||||
| validateField(prop, cb) | 对部分表单字段进行校验的方法 |
|
||||
| resetFields | 对整个表单进行重置,将所有字段值重置为空并移除校验结果 |
|
||||
| resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 |
|
||||
|
||||
### Form-Item Attributes
|
||||
|
||||
|
|
|
@ -54,12 +54,13 @@
|
|||
},
|
||||
validate(callback) {
|
||||
let valid = true;
|
||||
let count = 0;
|
||||
this.fields.forEach((field, index) => {
|
||||
field.validate('', errors => {
|
||||
if (errors) {
|
||||
valid = false;
|
||||
}
|
||||
if (typeof callback === 'function' && index === this.fields.length - 1) {
|
||||
if (typeof callback === 'function' && ++count === this.fields.length) {
|
||||
callback(valid);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -6,31 +6,11 @@
|
|||
{ 'is-without-controls': !controls}
|
||||
]"
|
||||
>
|
||||
<el-input
|
||||
:value="currentValue"
|
||||
@keydown.up.native="increase"
|
||||
@keydown.down.native="decrease"
|
||||
@blur="handleBlur"
|
||||
@input="handleInput"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
:class="{
|
||||
'is-active': inputActive
|
||||
}">
|
||||
<template slot="prepend" v-if="$slots.prepend">
|
||||
<slot name="prepend"></slot>
|
||||
</template>
|
||||
<template slot="append" v-if="$slots.append">
|
||||
<slot name="append"></slot>
|
||||
</template>
|
||||
</el-input>
|
||||
<span
|
||||
v-if="controls"
|
||||
class="el-input-number__decrease el-icon-minus"
|
||||
:class="{'is-disabled': minDisabled}"
|
||||
v-repeat-click="decrease"
|
||||
@mouseenter="activeInput(minDisabled)"
|
||||
@mouseleave="inactiveInput(minDisabled)"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
|
@ -38,10 +18,24 @@
|
|||
class="el-input-number__increase el-icon-plus"
|
||||
:class="{'is-disabled': maxDisabled}"
|
||||
v-repeat-click="increase"
|
||||
@mouseenter="activeInput(maxDisabled)"
|
||||
@mouseleave="inactiveInput(maxDisabled)"
|
||||
>
|
||||
</span>
|
||||
<el-input
|
||||
v-model.number="currentValue"
|
||||
@keydown.up.native="increase"
|
||||
@keydown.down.native="decrease"
|
||||
@blur="handleBlur"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
ref="input"
|
||||
>
|
||||
<template slot="prepend" v-if="$slots.prepend">
|
||||
<slot name="prepend"></slot>
|
||||
</template>
|
||||
<template slot="append" v-if="$slots.append">
|
||||
<slot name="append"></slot>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -50,29 +44,6 @@
|
|||
|
||||
export default {
|
||||
name: 'ElInputNumber',
|
||||
props: {
|
||||
step: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: Infinity
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
default: 0
|
||||
},
|
||||
disabled: Boolean,
|
||||
size: String,
|
||||
controls: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
repeatClick: {
|
||||
bind(el, binding, vnode) {
|
||||
|
@ -99,6 +70,29 @@
|
|||
components: {
|
||||
ElInput
|
||||
},
|
||||
props: {
|
||||
step: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: Infinity
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
default: 0
|
||||
},
|
||||
disabled: Boolean,
|
||||
size: String,
|
||||
controls: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
// correct the init value
|
||||
let value = this.value;
|
||||
|
@ -111,8 +105,7 @@
|
|||
value = this.max;
|
||||
}
|
||||
return {
|
||||
currentValue: value,
|
||||
inputActive: false
|
||||
currentValue: value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
@ -121,19 +114,18 @@
|
|||
},
|
||||
|
||||
currentValue(newVal, oldVal) {
|
||||
let value = Number(newVal);
|
||||
if (value <= this.max && value >= this.min) {
|
||||
this.$emit('change', value, oldVal);
|
||||
this.$emit('input', value);
|
||||
if (newVal <= this.max && newVal >= this.min) {
|
||||
this.$emit('change', newVal, oldVal);
|
||||
this.$emit('input', newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
minDisabled() {
|
||||
return this.value - this.step < this.min;
|
||||
return this.accSub(this.value, this.step) < this.min;
|
||||
},
|
||||
maxDisabled() {
|
||||
return this.value + this.step > this.max;
|
||||
return this.accAdd(this.value, this.step) > this.max;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -183,41 +175,19 @@
|
|||
return (arg1 + arg2) / m;
|
||||
},
|
||||
increase() {
|
||||
if (this.maxDisabled) return;
|
||||
const value = this.value || 0;
|
||||
if (value + this.step > this.max || this.disabled) return;
|
||||
this.currentValue = this.accAdd(this.step, value);
|
||||
if (this.maxDisabled) {
|
||||
this.inputActive = false;
|
||||
}
|
||||
if (this.accAdd(value, this.step) > this.max || this.disabled) return;
|
||||
this.currentValue = this.accAdd(value, this.step);
|
||||
},
|
||||
decrease() {
|
||||
if (this.minDisabled) return;
|
||||
const value = this.value || 0;
|
||||
if (value - this.step < this.min || this.disabled) return;
|
||||
if (this.accSub(value, this.step) < this.min || this.disabled) return;
|
||||
this.currentValue = this.accSub(value, this.step);
|
||||
if (this.minDisabled) {
|
||||
this.inputActive = false;
|
||||
}
|
||||
},
|
||||
activeInput(disabled) {
|
||||
if (!this.disabled && !disabled) {
|
||||
this.inputActive = true;
|
||||
}
|
||||
},
|
||||
inactiveInput(disabled) {
|
||||
if (!this.disabled && !disabled) {
|
||||
this.inputActive = false;
|
||||
}
|
||||
},
|
||||
handleBlur(event) {
|
||||
let value = Number(this.currentValue);
|
||||
if (isNaN(value) || value > this.max || value < this.min) {
|
||||
this.currentValue = this.value;
|
||||
} else {
|
||||
this.currentValue = value;
|
||||
}
|
||||
},
|
||||
handleInput(value) {
|
||||
this.currentValue = value;
|
||||
handleBlur() {
|
||||
this.$refs.input.setCurrentValue(this.currentValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
:min="min"
|
||||
:max="max"
|
||||
:form="form"
|
||||
:value="value"
|
||||
:value="currentValue"
|
||||
ref="input"
|
||||
@input="handleInput"
|
||||
@focus="handleFocus"
|
||||
|
@ -48,7 +48,8 @@
|
|||
<textarea
|
||||
v-else
|
||||
class="el-textarea__inner"
|
||||
v-model="currentValue"
|
||||
:value="currentValue"
|
||||
@input="handleInput"
|
||||
ref="textarea"
|
||||
:name="name"
|
||||
:placeholder="placeholder"
|
||||
|
@ -76,6 +77,13 @@
|
|||
|
||||
mixins: [emitter],
|
||||
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value,
|
||||
textareaStyle: {}
|
||||
};
|
||||
},
|
||||
|
||||
props: {
|
||||
value: [String, Number],
|
||||
placeholder: String,
|
||||
|
@ -108,6 +116,18 @@
|
|||
min: {}
|
||||
},
|
||||
|
||||
computed: {
|
||||
validating() {
|
||||
return this.$parent.validateState === 'validating';
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'value'(val, oldValue) {
|
||||
this.setCurrentValue(val);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleBlur(event) {
|
||||
this.$emit('blur', event);
|
||||
|
@ -129,46 +149,29 @@
|
|||
this.$emit('focus', event);
|
||||
},
|
||||
handleInput(event) {
|
||||
this.currentValue = event.target.value;
|
||||
this.setCurrentValue(event.target.value);
|
||||
},
|
||||
handleIconClick(event) {
|
||||
this.$emit('click', event);
|
||||
},
|
||||
setCurrentValue(value) {
|
||||
if (value === this.currentValue) return;
|
||||
this.$nextTick(_ => {
|
||||
this.resizeTextarea();
|
||||
});
|
||||
this.currentValue = value;
|
||||
this.$emit('input', value);
|
||||
this.$emit('change', value);
|
||||
this.dispatch('ElFormItem', 'el.form.change', [value]);
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value,
|
||||
textareaStyle: {}
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$on('inputSelect', this.inputSelect);
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.resizeTextarea();
|
||||
},
|
||||
|
||||
computed: {
|
||||
validating() {
|
||||
return this.$parent.validateState === 'validating';
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'value'(val, oldValue) {
|
||||
this.currentValue = val;
|
||||
},
|
||||
'currentValue'(val) {
|
||||
this.$nextTick(_ => {
|
||||
this.resizeTextarea();
|
||||
});
|
||||
this.$emit('input', val);
|
||||
this.$emit('change', val);
|
||||
this.dispatch('ElFormItem', 'el.form.change', [val]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -107,6 +107,14 @@
|
|||
},
|
||||
openActiveItemMenus() {
|
||||
let index = this.activeIndex;
|
||||
// 选中用户指定的路由对应的menu
|
||||
if (this.router) {
|
||||
const userSpecifiedIndexs = Object
|
||||
.keys(this.menuItems)
|
||||
.filter(k => this.menuItems[k].route)
|
||||
.filter(k => this.menuItems[k].route.path === this.$route.path);
|
||||
userSpecifiedIndexs.length && (index = this.activeIndex = userSpecifiedIndexs[0]);
|
||||
}
|
||||
if (!this.menuItems[index]) return;
|
||||
if (index && this.mode === 'vertical') {
|
||||
let indexPath = this.menuItems[index].indexPath;
|
||||
|
|
|
@ -100,6 +100,7 @@ export default {
|
|||
render(h) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
class={['btn-prev', { disabled: this.$parent.internalCurrentPage <= 1 }]}
|
||||
on-click={ this.$parent.prev }>
|
||||
<i class="el-icon el-icon-arrow-left"></i>
|
||||
|
@ -112,6 +113,7 @@ export default {
|
|||
render(h) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
class={[
|
||||
'btn-next',
|
||||
{ disabled: this.$parent.internalCurrentPage === this.$parent.internalPageCount || this.$parent.internalPageCount === 0 }
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<template>
|
||||
<label class="el-radio">
|
||||
<span class="el-radio__input">
|
||||
<span class="el-radio__inner"
|
||||
:class="{
|
||||
<span class="el-radio__input"
|
||||
:class="{
|
||||
'is-disabled': disabled,
|
||||
'is-checked': model === label,
|
||||
'is-focus': focus
|
||||
}"></span>
|
||||
}"
|
||||
>
|
||||
<span class="el-radio__inner"></span>
|
||||
<input
|
||||
class="el-radio__original"
|
||||
:value="label"
|
||||
|
|
|
@ -92,11 +92,6 @@
|
|||
},
|
||||
value() {
|
||||
this.dispatch('ElSelect', 'setSelected');
|
||||
},
|
||||
visible() {
|
||||
this.$nextTick(() => {
|
||||
this.dispatch('ElSelectDropdown', 'updatePopper');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -233,7 +233,9 @@
|
|||
},
|
||||
|
||||
query(val) {
|
||||
this.broadcast('ElSelectDropdown', 'updatePopper');
|
||||
this.$nextTick(() => {
|
||||
this.broadcast('ElSelectDropdown', 'updatePopper');
|
||||
});
|
||||
this.hoverIndex = -1;
|
||||
if (this.multiple && this.filterable) {
|
||||
this.resetInputHeight();
|
||||
|
@ -557,7 +559,7 @@
|
|||
|
||||
deleteTag(event, tag) {
|
||||
let index = this.selected.indexOf(tag);
|
||||
if (index > -1) {
|
||||
if (index > -1 && !this.disabled) {
|
||||
this.value.splice(index, 1);
|
||||
}
|
||||
event.stopPropagation();
|
||||
|
|
|
@ -38,7 +38,7 @@ export default {
|
|||
<tbody>
|
||||
{
|
||||
this._l(this.data, (row, $index) =>
|
||||
<tr
|
||||
[<tr
|
||||
style={ this.rowStyle ? this.getRowStyle(row, $index) : null }
|
||||
key={ this.table.rowKey ? this.getKeyOfRow(row, $index) : $index }
|
||||
on-dblclick={ ($event) => this.handleDoubleClick($event, row) }
|
||||
|
@ -46,7 +46,7 @@ export default {
|
|||
on-contextmenu={ ($event) => this.handleContextMenu($event, row) }
|
||||
on-mouseenter={ _ => this.handleMouseEnter($index) }
|
||||
on-mouseleave={ _ => this.handleMouseLeave() }
|
||||
class={ this.getRowClass(row, $index) }>
|
||||
class={ [this.getRowClass(row, $index)] }>
|
||||
{
|
||||
this._l(this.columns, (column, cellIndex) =>
|
||||
<td
|
||||
|
@ -62,7 +62,15 @@ export default {
|
|||
{
|
||||
!this.fixed && this.layout.scrollY && this.layout.gutterWidth ? <td class="gutter" /> : ''
|
||||
}
|
||||
</tr>
|
||||
</tr>,
|
||||
this.store.states.expandRows.indexOf(row) > -1
|
||||
? (<tr>
|
||||
<td colspan={ this.columns.length } class="el-table__expanded-cell">
|
||||
{ this.$parent.renderExpanded ? this.$parent.renderExpanded.call(this._renderProxy, h, { row, $index, store: this.store, _self: this.$parent.$vnode.context }) : ''}
|
||||
</td>
|
||||
</tr>)
|
||||
: ''
|
||||
]
|
||||
)
|
||||
}
|
||||
</tbody>
|
||||
|
@ -95,6 +103,8 @@ export default {
|
|||
const newRow = rows[data.indexOf(newVal)];
|
||||
if (oldRow) {
|
||||
oldRow.classList.remove('current-row');
|
||||
} else if (rows) {
|
||||
[].forEach.call(rows, row => row.classList.remove('current-row'));
|
||||
}
|
||||
if (newRow) {
|
||||
newRow.classList.add('current-row');
|
||||
|
@ -180,7 +190,7 @@ export default {
|
|||
|
||||
if (cell) {
|
||||
const column = getColumnByCell(table, cell);
|
||||
const hoverState = table.hoverState = { cell, column, row };
|
||||
const hoverState = table.hoverState = {cell, column, row};
|
||||
table.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event);
|
||||
}
|
||||
|
||||
|
@ -230,6 +240,10 @@ export default {
|
|||
this.store.commit('setCurrentRow', row);
|
||||
|
||||
table.$emit('row-click', row, event, column);
|
||||
},
|
||||
|
||||
handleExpandClick(row) {
|
||||
this.store.commit('toggleRowExpanded', row);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,6 +16,12 @@ const defaults = {
|
|||
order: '',
|
||||
className: 'el-table-column--selection'
|
||||
},
|
||||
expand: {
|
||||
width: 48,
|
||||
minWidth: 48,
|
||||
realWidth: 48,
|
||||
order: ''
|
||||
},
|
||||
index: {
|
||||
width: 48,
|
||||
minWidth: 48,
|
||||
|
@ -48,6 +54,21 @@ const forced = {
|
|||
return <div>{ $index + 1 }</div>;
|
||||
},
|
||||
sortable: false
|
||||
},
|
||||
expand: {
|
||||
renderHeader: function(h, {}) {
|
||||
return '';
|
||||
},
|
||||
renderCell: function(h, { row, store }, proxy) {
|
||||
const expanded = store.states.expandRows.indexOf(row) > -1;
|
||||
return <div class={ 'el-table__expand-icon ' + (expanded ? 'el-table__expand-icon--expanded' : '') }
|
||||
on-click={ () => proxy.handleExpandClick(row) }>
|
||||
<i class='el-icon el-icon-arrow-right'></i>
|
||||
</div>;
|
||||
},
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
className: 'el-table__expand-column'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -114,6 +135,7 @@ export default {
|
|||
context: {},
|
||||
columnKey: String,
|
||||
align: String,
|
||||
headerAlign: String,
|
||||
showTooltipWhenOverflow: Boolean,
|
||||
showOverflowTooltip: Boolean,
|
||||
fixed: [Boolean, String],
|
||||
|
@ -199,6 +221,7 @@ export default {
|
|||
isColumnGroup,
|
||||
context: this.context,
|
||||
align: this.align ? 'is-' + this.align : null,
|
||||
headerAlign: this.headerAlign ? 'is-' + this.headerAlign : (this.align ? 'is-' + this.align : null),
|
||||
sortable: this.sortable,
|
||||
sortMethod: this.sortMethod,
|
||||
resizable: this.resizable,
|
||||
|
@ -217,9 +240,35 @@ export default {
|
|||
|
||||
objectAssign(column, forced[type] || {});
|
||||
|
||||
this.columnConfig = column;
|
||||
|
||||
let renderCell = column.renderCell;
|
||||
let _self = this;
|
||||
|
||||
if (type === 'expand') {
|
||||
owner.renderExpanded = function(h, data) {
|
||||
if (_self.$vnode.data.inlineTemplate) {
|
||||
data._self = _self.context || data._self;
|
||||
if (Object.prototype.toString.call(data._self) === '[object Object]') {
|
||||
for (let prop in data._self) {
|
||||
if (!data.hasOwnProperty(prop)) {
|
||||
data[prop] = data._self[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
data._staticTrees = _self._staticTrees;
|
||||
data.$options.staticRenderFns = _self.$options.staticRenderFns;
|
||||
return _self.customRender.call(data);
|
||||
}
|
||||
};
|
||||
|
||||
column.renderCell = function(h, data) {
|
||||
return <div class="cell">{ renderCell(h, data, this._renderProxy) }</div>;
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
column.renderCell = function(h, data) {
|
||||
if (_self.$vnode.data.inlineTemplate) {
|
||||
renderCell = function() {
|
||||
|
@ -254,8 +303,6 @@ export default {
|
|||
</el-tooltip>
|
||||
: <div class="cell">{ renderCell(h, data) }</div>;
|
||||
};
|
||||
|
||||
this.columnConfig = column;
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
|
@ -300,6 +347,12 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
headerAlign(newVal) {
|
||||
if (this.columnConfig) {
|
||||
this.columnConfig.headerAlign = newVal ? 'is-' + newVal : this.align;
|
||||
}
|
||||
},
|
||||
|
||||
width(newVal) {
|
||||
if (this.columnConfig) {
|
||||
this.columnConfig.width = newVal;
|
||||
|
|
|
@ -103,7 +103,7 @@ export default {
|
|||
on-mouseout={ this.handleMouseOut }
|
||||
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
||||
on-click={ ($event) => this.handleClick($event, column) }
|
||||
class={ [column.id, column.order, column.align, column.className || '', rowIndex === 0 && this.isCellHidden(cellIndex) ? 'is-hidden' : '', !column.children ? 'is-leaf' : ''] }>
|
||||
class={ [column.id, column.order, column.headerAlign, column.className || '', rowIndex === 0 && this.isCellHidden(cellIndex) ? 'is-hidden' : '', !column.children ? 'is-leaf' : ''] }>
|
||||
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : ''] }>
|
||||
{
|
||||
column.renderHeader
|
||||
|
@ -112,9 +112,9 @@ export default {
|
|||
}
|
||||
{
|
||||
column.sortable
|
||||
? <span class="caret-wrapper" on-click={ ($event) => this.handleHeaderClick($event, column) }>
|
||||
<i class="sort-caret ascending"></i>
|
||||
<i class="sort-caret descending"></i>
|
||||
? <span class="caret-wrapper">
|
||||
<i class="sort-caret ascending" on-click={ ($event) => this.handleHeaderClick($event, column, 'ascending')}></i>
|
||||
<i class="sort-caret descending" on-click={ ($event) => this.handleHeaderClick($event, column, 'descending')}></i>
|
||||
</span>
|
||||
: ''
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ export default {
|
|||
document.body.style.cursor = '';
|
||||
},
|
||||
|
||||
handleHeaderClick(event, column) {
|
||||
handleHeaderClick(event, column, order) {
|
||||
let target = event.target;
|
||||
while (target && target.tagName !== 'TH') {
|
||||
target = target.parentNode;
|
||||
|
@ -362,15 +362,14 @@ export default {
|
|||
sortProp = column.property;
|
||||
}
|
||||
|
||||
if (!column.order) {
|
||||
sortOrder = column.order = 'ascending';
|
||||
} else if (column.order === 'ascending') {
|
||||
sortOrder = column.order = 'descending';
|
||||
} else {
|
||||
if (column.order === order) {
|
||||
sortOrder = column.order = null;
|
||||
states.sortingColumn = null;
|
||||
sortProp = null;
|
||||
} else {
|
||||
sortOrder = column.order = order;
|
||||
}
|
||||
|
||||
states.sortProp = sortProp;
|
||||
states.sortOrder = sortOrder;
|
||||
|
||||
|
|
|
@ -69,7 +69,9 @@ const TableStore = function(table, initialState = {}) {
|
|||
selectable: null,
|
||||
currentRow: null,
|
||||
hoverRow: null,
|
||||
filters: {}
|
||||
filters: {},
|
||||
expandRows: [],
|
||||
defaultExpandAll: false
|
||||
};
|
||||
|
||||
for (let prop in initialState) {
|
||||
|
@ -85,6 +87,15 @@ TableStore.prototype.mutations = {
|
|||
states._data = data;
|
||||
states.data = sortData((data || []), states);
|
||||
|
||||
states.data.forEach((item) => {
|
||||
if (!item.$extra) {
|
||||
Object.defineProperty(item, '$extra', {
|
||||
value: {},
|
||||
enumerable: false
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.updateCurrentRow();
|
||||
|
||||
if (!states.reserveSelection) {
|
||||
|
@ -114,6 +125,11 @@ TableStore.prototype.mutations = {
|
|||
}
|
||||
}
|
||||
|
||||
const defaultExpandAll = states.defaultExpandAll;
|
||||
if (defaultExpandAll) {
|
||||
this.states.expandRows = (states.data || []).slice(0);
|
||||
}
|
||||
|
||||
Vue.nextTick(() => this.table.updateScrollY());
|
||||
},
|
||||
|
||||
|
@ -218,6 +234,26 @@ TableStore.prototype.mutations = {
|
|||
this.updateAllSelected();
|
||||
},
|
||||
|
||||
toggleRowExpanded: function(states, row, expanded) {
|
||||
const expandRows = states.expandRows;
|
||||
if (typeof expanded !== 'undefined') {
|
||||
const index = expandRows.indexOf(row);
|
||||
if (expanded) {
|
||||
if (index === -1) expandRows.push(row);
|
||||
} else {
|
||||
if (index !== -1) expandRows.splice(index, 1);
|
||||
}
|
||||
} else {
|
||||
const index = expandRows.indexOf(row);
|
||||
if (index === -1) {
|
||||
expandRows.push(row);
|
||||
} else {
|
||||
expandRows.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.table.$emit('expand', row, expandRows.indexOf(row) !== -1);
|
||||
},
|
||||
|
||||
toggleAllSelection: debounce(10, function(states) {
|
||||
const data = states.data || [];
|
||||
const value = !states.isAllSelected;
|
||||
|
@ -286,6 +322,22 @@ TableStore.prototype.clearSelection = function() {
|
|||
}
|
||||
};
|
||||
|
||||
TableStore.prototype.setExpandRowKeys = function(rowKeys) {
|
||||
const expandRows = [];
|
||||
const data = this.states.data;
|
||||
const rowKey = this.states.rowKey;
|
||||
if (!rowKey) throw new Error('[Table] prop row-key should not be empty.');
|
||||
const keysMap = getKeysMap(data, rowKey);
|
||||
rowKeys.forEach((key) => {
|
||||
const info = keysMap[key];
|
||||
if (info) {
|
||||
expandRows.push(info.row);
|
||||
}
|
||||
});
|
||||
|
||||
this.states.expandRows = expandRows;
|
||||
};
|
||||
|
||||
TableStore.prototype.toggleRowSelection = function(row, selected) {
|
||||
const changed = toggleRowSelection(this.states, row, selected);
|
||||
if (changed) {
|
||||
|
@ -395,6 +447,8 @@ TableStore.prototype.commit = function(name, ...args) {
|
|||
const mutations = this.mutations;
|
||||
if (mutations[name]) {
|
||||
mutations[name].apply(this, [this.states].concat(args));
|
||||
} else {
|
||||
throw new Error(`Action not found: ${name}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -164,7 +164,11 @@
|
|||
|
||||
highlightCurrentRow: Boolean,
|
||||
|
||||
emptyText: String
|
||||
emptyText: String,
|
||||
|
||||
expandRowKeys: Array,
|
||||
|
||||
defaultExpandAll: Boolean
|
||||
},
|
||||
|
||||
components: {
|
||||
|
@ -356,6 +360,10 @@
|
|||
handler(val) {
|
||||
this.store.commit('setData', val);
|
||||
}
|
||||
},
|
||||
|
||||
expandRowKeys(newVal) {
|
||||
this.store.setExpandRowKeys(newVal);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -372,7 +380,8 @@
|
|||
|
||||
data() {
|
||||
const store = new TableStore(this, {
|
||||
rowKey: this.rowKey
|
||||
rowKey: this.rowKey,
|
||||
defaultExpandAll: this.defaultExpandAll
|
||||
});
|
||||
const layout = new TableLayout({
|
||||
store,
|
||||
|
@ -383,6 +392,7 @@
|
|||
return {
|
||||
store,
|
||||
layout,
|
||||
renderExpanded: null,
|
||||
resizeProxyVisible: false
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
<template>
|
||||
<div class="el-tab-pane">
|
||||
<div class="el-tab-pane__content" v-show="active">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
module.exports = {
|
||||
name: 'el-tab-pane',
|
||||
|
@ -12,73 +19,33 @@
|
|||
|
||||
data() {
|
||||
return {
|
||||
counter: 0,
|
||||
transition: '',
|
||||
paneStyle: {
|
||||
position: 'relative'
|
||||
},
|
||||
isClosable: null,
|
||||
index: ''
|
||||
index: null
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
const propsData = this.$options.propsData;
|
||||
if (propsData && typeof propsData.closable !== 'undefined') {
|
||||
this.isClosable = propsData.closable === '' || propsData.closable;
|
||||
} else {
|
||||
this.isClosable = this.$parent.closable;
|
||||
}
|
||||
if (!this.index) {
|
||||
this.index = this.$parent.$children.indexOf(this) + 1 + '';
|
||||
}
|
||||
if (this.$parent.panes) {
|
||||
this.$parent.panes.push(this);
|
||||
computed: {
|
||||
isClosable() {
|
||||
return this.closable || this.$parent.closable;
|
||||
},
|
||||
active() {
|
||||
return this.$parent.currentName === (this.name || this.index);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
show() {
|
||||
return this.$parent.currentName === this.index;
|
||||
}
|
||||
created() {
|
||||
this.$parent.$forceUpdate();
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
if (this.$el && this.$el.parentNode) {
|
||||
this.$el.parentNode.removeChild(this.$el);
|
||||
}
|
||||
const panes = this.$parent.panes;
|
||||
if (panes) {
|
||||
panes.splice(this, panes.indexOf(this));
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
name: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.index = val;
|
||||
}
|
||||
},
|
||||
closable(val) {
|
||||
this.isClosable = val;
|
||||
},
|
||||
'$parent.currentName'(newValue, oldValue) {
|
||||
if (this.index === newValue) {
|
||||
this.transition = newValue > oldValue ? 'slideInRight' : 'slideInLeft';
|
||||
}
|
||||
if (this.index === oldValue) {
|
||||
this.transition = oldValue > newValue ? 'slideInRight' : 'slideInLeft';
|
||||
}
|
||||
},
|
||||
label() {
|
||||
this.$parent.$forceUpdate();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="el-tab-pane" v-show="show && $slots.default">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -4,69 +4,84 @@
|
|||
|
||||
props: {
|
||||
type: String,
|
||||
tabPosition: String,
|
||||
activeName: String,
|
||||
closable: false,
|
||||
tabWidth: 0
|
||||
closable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
children: null,
|
||||
activeTab: null,
|
||||
currentName: 0,
|
||||
panes: []
|
||||
currentName: this.value || this.activeName
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
activeName: {
|
||||
handler(val) {
|
||||
this.currentName = val;
|
||||
}
|
||||
activeName(val) {
|
||||
this.currentName = val;
|
||||
},
|
||||
value(val) {
|
||||
this.currentName = val;
|
||||
},
|
||||
currentName(val) {
|
||||
this.$emit('input', val);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleTabRemove(tab, event) {
|
||||
event.stopPropagation();
|
||||
let tabs = this.$children;
|
||||
const tabs = this.$children;
|
||||
|
||||
var index = tabs.indexOf(tab);
|
||||
tab.$destroy(true);
|
||||
let index = tabs.indexOf(tab);
|
||||
tab.$destroy();
|
||||
|
||||
if (tab.index === this.currentName) {
|
||||
let nextChild = tabs[index];
|
||||
let prevChild = tabs[index - 1];
|
||||
|
||||
while (prevChild && prevChild.disabled) {
|
||||
prevChild = tabs[tabs.indexOf(prevChild) - 1];
|
||||
}
|
||||
|
||||
this.currentName = nextChild
|
||||
? nextChild.index
|
||||
: prevChild
|
||||
? prevChild.index
|
||||
: '-1';
|
||||
}
|
||||
this.$emit('tab-remove', tab);
|
||||
this.$forceUpdate();
|
||||
},
|
||||
handleTabClick(tab, event) {
|
||||
if (tab.disabled) return;
|
||||
this.currentName = tab.index;
|
||||
this.$emit('tab-click', tab, event);
|
||||
},
|
||||
calcBarStyle() {
|
||||
if (this.type || !this.$refs.tabs) return {};
|
||||
var style = {};
|
||||
var offset = 0;
|
||||
var tabWidth = 0;
|
||||
|
||||
this.$children.every((panel, index) => {
|
||||
this.$nextTick(_ => {
|
||||
if (tab.active) {
|
||||
let nextChild = tabs[index];
|
||||
let prevChild = tabs[index - 1];
|
||||
let nextActiveTab = nextChild || prevChild || null;
|
||||
|
||||
if (nextActiveTab) {
|
||||
this.currentName = nextActiveTab.name || nextActiveTab.index;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleTabClick(tab, tabName, event) {
|
||||
if (tab.disabled) return;
|
||||
this.currentName = tabName;
|
||||
this.$emit('tab-click', tab, event);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$forceUpdate();
|
||||
},
|
||||
render(h) {
|
||||
let {
|
||||
type,
|
||||
handleTabRemove,
|
||||
handleTabClick,
|
||||
currentName
|
||||
} = this;
|
||||
|
||||
const getBarStyle = () => {
|
||||
if (this.type || !this.$refs.tabs) return {};
|
||||
let style = {};
|
||||
let offset = 0;
|
||||
let tabWidth = 0;
|
||||
|
||||
this.$children.every((tab, index) => {
|
||||
let $el = this.$refs.tabs[index];
|
||||
if (!$el) { return false; }
|
||||
if (panel.index !== this.currentName) {
|
||||
|
||||
if (!tab.active) {
|
||||
offset += $el.clientWidth;
|
||||
return true;
|
||||
} else {
|
||||
|
@ -79,51 +94,45 @@
|
|||
style.transform = `translateX(${offset}px)`;
|
||||
|
||||
return style;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.currentName = this.activeName || this.$children[0] && this.$children[0].index || '1';
|
||||
this.$nextTick(() => {
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
render(h) {
|
||||
let {
|
||||
type,
|
||||
panes, // eslint-disable-line
|
||||
handleTabRemove,
|
||||
handleTabClick,
|
||||
currentName
|
||||
} = this;
|
||||
|
||||
const barStyle = this.calcBarStyle();
|
||||
const activeBar = !type
|
||||
? <div class="el-tabs__active-bar" style={barStyle}></div>
|
||||
: null;
|
||||
};
|
||||
|
||||
const tabs = this.$children.map((tab, index) => {
|
||||
let btnClose = h('span', {
|
||||
class: {
|
||||
'el-icon-close': true
|
||||
},
|
||||
on: { click: (ev) => { handleTabRemove(tab, ev); } }
|
||||
});
|
||||
const _tab = h('div', {
|
||||
class: {
|
||||
'el-tabs__item': true,
|
||||
'is-active': currentName === tab.index,
|
||||
'is-disabled': tab.disabled,
|
||||
'is-closable': tab.isClosable
|
||||
},
|
||||
ref: 'tabs',
|
||||
refInFor: true,
|
||||
on: { click: (ev) => { handleTabClick(tab, ev); } }
|
||||
}, [
|
||||
tab.labelContent ? tab.labelContent.call(this._renderProxy, h, tab) : tab.label,
|
||||
tab.isClosable ? btnClose : null,
|
||||
index === 0 ? activeBar : null
|
||||
]);
|
||||
return _tab;
|
||||
let tabName = tab.name || tab.index || index;
|
||||
if (currentName === undefined && index === 0) {
|
||||
this.currentName = tabName;
|
||||
}
|
||||
|
||||
tab.index = index;
|
||||
|
||||
const activeBar = !type && index === 0
|
||||
? <div class="el-tabs__active-bar" style={getBarStyle()}></div>
|
||||
: null;
|
||||
|
||||
const btnClose = tab.isClosable
|
||||
? <span class="el-icon-close" on-click={(ev) => { handleTabRemove(tab, ev); }}></span>
|
||||
: null;
|
||||
|
||||
const tabLabelContent = tab.labelContent
|
||||
? tab.labelContent.call(this._renderProxy, h, tab)
|
||||
: tab.label;
|
||||
|
||||
return (
|
||||
<div
|
||||
class={{
|
||||
'el-tabs__item': true,
|
||||
'is-active': tab.active,
|
||||
'is-disabled': tab.disabled,
|
||||
'is-closable': tab.isClosable
|
||||
}}
|
||||
ref="tabs"
|
||||
refInFor
|
||||
on-click={(ev) => { handleTabClick(tab, tabName, ev); }}
|
||||
>
|
||||
{tabLabelContent}
|
||||
{btnClose}
|
||||
{activeBar}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div class={{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "element-theme-default",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.9",
|
||||
"description": "Element component default theme.",
|
||||
"main": "lib/index.css",
|
||||
"style": "lib/index.css",
|
||||
|
|
|
@ -19,6 +19,83 @@
|
|||
line-height: 1;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
|
||||
@when disabled {
|
||||
.el-checkbox__inner {
|
||||
background-color: var(--checkbox-disabled-input-fill);
|
||||
border-color: var(--checkbox-disabled-input-border-color);
|
||||
cursor: not-allowed;
|
||||
|
||||
&::after {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--checkbox-disabled-icon-color);
|
||||
}
|
||||
|
||||
& + .el-checkbox__label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
&.is-checked {
|
||||
.el-checkbox__inner {
|
||||
background-color: var(--checkbox-disabled-checked-input-fill);
|
||||
border-color: var(--checkbox-disabled-checked-input-border-color);
|
||||
|
||||
&::after {
|
||||
border-color: var(--checkbox-disabled-checked-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.is-indeterminate {
|
||||
.el-checkbox__inner {
|
||||
background-color: var(--checkbox-disabled-checked-input-fill);
|
||||
border-color: var(--checkbox-disabled-checked-input-border-color);
|
||||
|
||||
&::before {
|
||||
border-color: var(--checkbox-disabled-checked-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
& + .el-checkbox__label {
|
||||
color: var(--disabled-color-base);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
@when checked {
|
||||
.el-checkbox__inner {
|
||||
background-color: var(--checkbox-checked-input-fill);
|
||||
border-color: var(--checkbox-checked-input-border-color);
|
||||
|
||||
&::after {
|
||||
transform: rotate(45deg) scaleY(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@when focus {
|
||||
.el-checkbox__inner {
|
||||
border-color: var(--checkbox-input-border-color-hover);
|
||||
}
|
||||
}
|
||||
@when indeterminate {
|
||||
.el-checkbox__inner {
|
||||
background-color: var(--checkbox-checked-input-fill);
|
||||
border-color: var(--checkbox-checked-input-border-color);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
border: 1px solid var(--checkbox-checked-icon-color);
|
||||
margin-top: -1px;
|
||||
left: 3px;
|
||||
right: 3px;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@e inner {
|
||||
display: inline-block;
|
||||
|
@ -31,7 +108,7 @@
|
|||
transition: border-color .25s cubic-bezier(.71,-.46,.29,1.46),
|
||||
background-color .25s cubic-bezier(.71,-.46,.29,1.46);
|
||||
|
||||
&:not(.is-disabled):hover {
|
||||
&:hover {
|
||||
border-color: var(--checkbox-input-border-color-hover);
|
||||
}
|
||||
|
||||
|
@ -50,72 +127,6 @@
|
|||
transition: transform .15s cubic-bezier(.71,-.46,.88,.6) .05s;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
@when disabled {
|
||||
background-color: var(--checkbox-disabled-input-fill);
|
||||
border-color: var(--checkbox-disabled-input-border-color);
|
||||
cursor: not-allowed;
|
||||
|
||||
&::after {
|
||||
cursor: not-allowed;
|
||||
border-color: var(--checkbox-disabled-icon-color);
|
||||
}
|
||||
|
||||
& + .el-checkbox__label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@when checked {
|
||||
background-color: var(--checkbox-checked-input-fill);
|
||||
border-color: var(--checkbox-checked-input-border-color);
|
||||
|
||||
&::after {
|
||||
transform: rotate(45deg) scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@when focus {
|
||||
border-color: var(--checkbox-input-border-color-hover);
|
||||
}
|
||||
|
||||
&.is-disabled.is-checked {
|
||||
background-color: var(--checkbox-disabled-checked-input-fill);
|
||||
border-color: var(--checkbox-disabled-checked-input-border-color);
|
||||
|
||||
&::after {
|
||||
border-color: var(--checkbox-disabled-checked-icon-color);
|
||||
}
|
||||
}
|
||||
|
||||
@when indeterminate {
|
||||
background-color: var(--checkbox-checked-input-fill);
|
||||
border-color: var(--checkbox-checked-input-border-color);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
border: 1px solid var(--checkbox-checked-icon-color);
|
||||
margin-top: -1px;
|
||||
left: 3px;
|
||||
right: 3px;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-disabled.is-indeterminate {
|
||||
background-color: var(--checkbox-disabled-checked-input-fill);
|
||||
border-color: var(--checkbox-disabled-checked-input-border-color);
|
||||
|
||||
&::before {
|
||||
border-color: var(--checkbox-disabled-checked-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@e original {
|
||||
|
|
|
@ -7,26 +7,41 @@
|
|||
}
|
||||
|
||||
@for $i from 1 to 24 {
|
||||
.el-col-$i,
|
||||
.el-col-xs-$i {
|
||||
.el-col-$i {
|
||||
width: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
.el-col-offset-$i,
|
||||
.el-col-xs-offset-$i {
|
||||
.el-col-offset-$i {
|
||||
margin-left: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
.el-col-pull-$i,
|
||||
.el-col-xs-pull-$i {
|
||||
.el-col-pull-$i {
|
||||
position: relative;
|
||||
right: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
.el-col-push-$i,
|
||||
.el-col-xs-push-$i {
|
||||
.el-col-push-$i {
|
||||
position: relative;
|
||||
left: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@for $i from 1 to 24 {
|
||||
.el-col-xs-$i {
|
||||
width: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
.el-col-xs-offset-$i {
|
||||
margin-left: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
.el-col-xs-pull-$i {
|
||||
position: relative;
|
||||
right: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
.el-col-xs-push-$i {
|
||||
position: relative;
|
||||
left: calc(1 / 24 * $(i) * 100)%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
@for $i from 1 to 24 {
|
||||
.el-col-sm-$i {
|
||||
|
|
|
@ -23,9 +23,14 @@
|
|||
color: #99A9BF;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
|
||||
&:not(.is-disabled) ~ .el-input .el-input__inner:not(.is-disabled) {
|
||||
border-color: var(--input-focus-border);
|
||||
}
|
||||
}
|
||||
|
||||
@when disabled {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
white-space: nowrap;
|
||||
padding: 2px 5px;
|
||||
color: var(--pagination-color);
|
||||
@utils-clearfix;
|
||||
|
||||
span,
|
||||
button {
|
||||
|
|
|
@ -24,6 +24,54 @@
|
|||
line-height: 1;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
|
||||
@when disabled {
|
||||
.el-radio__inner {
|
||||
background-color: var(--radio-disabled-input-fill);
|
||||
border-color: var(--radio-disabled-input-border-color);
|
||||
cursor: not-allowed;
|
||||
|
||||
&::after {
|
||||
cursor: not-allowed;
|
||||
background-color: var(--radio-disabled-icon-color);
|
||||
}
|
||||
|
||||
& + .el-radio__label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
&.is-checked {
|
||||
.el-radio__inner {
|
||||
background-color: var(--radio-disabled-checked-input-fill);
|
||||
border-color: var(--radio-disabled-checked-input-border-color);
|
||||
|
||||
&::after {
|
||||
background-color: var(--radio-disabled-checked-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
& + .el-radio__label {
|
||||
color: var(--disabled-color-base);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@when checked {
|
||||
.el-radio__inner {
|
||||
border-color: var(--radio-checked-input-border-color);
|
||||
background: var(--radio-checked-icon-color);
|
||||
|
||||
&::after {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@when focus {
|
||||
.el-radio__inner {
|
||||
border-color: var(--radio-input-border-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
@e inner {
|
||||
border: var(--radio-input-border);
|
||||
|
@ -34,7 +82,7 @@
|
|||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:not(.is-disabled):hover {
|
||||
&:hover {
|
||||
border-color: var(--radio-input-border-color-hover);
|
||||
}
|
||||
|
||||
|
@ -47,43 +95,6 @@
|
|||
transform: translate(-50%, -50%) scale(0);
|
||||
transition: transform .15s cubic-bezier(.71,-.46,.88,.6);
|
||||
}
|
||||
|
||||
@when disabled {
|
||||
background-color: var(--radio-disabled-input-fill);
|
||||
border-color: var(--radio-disabled-input-border-color);
|
||||
cursor: not-allowed;
|
||||
|
||||
&::after {
|
||||
cursor: not-allowed;
|
||||
background-color: var(--radio-disabled-icon-color);
|
||||
}
|
||||
|
||||
& + .el-radio__label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@when checked {
|
||||
border-color: var(--radio-checked-input-border-color);
|
||||
background: var(--radio-checked-icon-color);
|
||||
|
||||
&::after {
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@when focus {
|
||||
border-color: var(--radio-input-border-color-hover);
|
||||
}
|
||||
|
||||
&.is-disabled.is-checked {
|
||||
background-color: var(--radio-disabled-checked-input-fill);
|
||||
border-color: var(--radio-disabled-checked-input-border-color);
|
||||
|
||||
&::after {
|
||||
background-color: var(--radio-disabled-checked-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@e original {
|
||||
|
|
|
@ -66,6 +66,44 @@
|
|||
color: #5e6d82;
|
||||
}
|
||||
|
||||
@e expand-column {
|
||||
.cell {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@e expand-icon {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s ease-in-out;
|
||||
height: 40px;
|
||||
|
||||
@m expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
> .el-icon {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -5px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
}
|
||||
|
||||
@e expanded-cell {
|
||||
padding: 20px 50px;
|
||||
background-color: #f9fafc;
|
||||
box-shadow: inset 0 2px 0 #f4f4f4;
|
||||
|
||||
&:hover {
|
||||
background-color: #f9fafc !important;
|
||||
}
|
||||
}
|
||||
|
||||
@modifier fit {
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
|
|
|
@ -147,10 +147,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
@b tab-pane {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.slideInRight-transition,
|
||||
|
|
|
@ -133,12 +133,12 @@
|
|||
this.tree.$emit('current-change', store.currentNode ? store.currentNode.data : null, store.currentNode);
|
||||
this.tree.currentNode = this;
|
||||
if (this.tree.expandOnClickNode) {
|
||||
this.handleExpandIconClick(event);
|
||||
this.handleExpandIconClick();
|
||||
}
|
||||
this.tree.$emit('node-click', this.node.data, this.node, this);
|
||||
},
|
||||
|
||||
handleExpandIconClick(event) {
|
||||
handleExpandIconClick() {
|
||||
if (this.expanded) {
|
||||
this.node.collapse();
|
||||
} else {
|
||||
|
|
|
@ -141,7 +141,7 @@ if (typeof window !== 'undefined' && window.Vue) {
|
|||
};
|
||||
|
||||
module.exports = {
|
||||
version: '1.0.8',
|
||||
version: '1.0.9',
|
||||
locale: locale.use,
|
||||
install,
|
||||
Loading,
|
||||
|
|
|
@ -91,6 +91,31 @@ describe('DatePicker', () => {
|
|||
}, DELAY);
|
||||
});
|
||||
|
||||
it('disabled clear value', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-date-picker v-model="value" ref="compo" :clearable="false"></el-date-picker>
|
||||
`,
|
||||
data() {
|
||||
return { value: '' };
|
||||
}
|
||||
}, true);
|
||||
const input = vm.$el.querySelector('input');
|
||||
|
||||
input.focus();
|
||||
setTimeout(_ => {
|
||||
const $el = vm.$refs.compo.picker.$el;
|
||||
$el.querySelector('td.available').click();
|
||||
vm.$nextTick(_ => {
|
||||
vm.$el.querySelector('.el-input__icon').click();
|
||||
setTimeout(_ => {
|
||||
expect(vm.value).to.be.exist;
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('reset', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
|
@ -120,6 +145,46 @@ describe('DatePicker', () => {
|
|||
}, DELAY);
|
||||
});
|
||||
|
||||
it('change event', done => {
|
||||
let inputValue;
|
||||
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-date-picker
|
||||
ref="compo"
|
||||
v-model="value"
|
||||
format="yyyy-MM"
|
||||
@change="handleChange" />`,
|
||||
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
inputValue = val;
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return { value: '' };
|
||||
}
|
||||
}, true);
|
||||
|
||||
const input = vm.$el.querySelector('input');
|
||||
|
||||
input.blur();
|
||||
input.focus();
|
||||
|
||||
setTimeout(_ => {
|
||||
const picker = vm.$refs.compo.picker;
|
||||
|
||||
picker.$el.querySelector('td.available').click();
|
||||
vm.$nextTick(_ => {
|
||||
const date = picker.date;
|
||||
|
||||
expect(inputValue).to.equal(`${date.getFullYear()}-${date.getMonth() + 1 }`);
|
||||
done();
|
||||
});
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
describe('keydown', () => {
|
||||
let input;
|
||||
let keyDown = function(el, keyCode) {
|
||||
|
|
|
@ -38,22 +38,14 @@ describe('InputNumber', () => {
|
|||
let input = vm.$el.querySelector('input');
|
||||
let btnDecrease = vm.$el.querySelector('.el-input-number__decrease');
|
||||
|
||||
triggerEvent(btnDecrease, 'mouseenter');
|
||||
triggerEvent(btnDecrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelector('.el-input.is-active')).to.exist;
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(4);
|
||||
expect(input.value).to.be.equal('4');
|
||||
|
||||
triggerEvent(btnDecrease, 'mouseleave');
|
||||
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.$el.querySelector('.el-input.is-active')).to.not.exist;
|
||||
done();
|
||||
});
|
||||
}, 300);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('increase', done => {
|
||||
vm = createVue({
|
||||
|
@ -74,11 +66,11 @@ describe('InputNumber', () => {
|
|||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(2.5);
|
||||
expect(input.value).to.be.equal('2.5');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
it('disabled', done => {
|
||||
vm = createVue({
|
||||
|
@ -100,19 +92,19 @@ describe('InputNumber', () => {
|
|||
triggerEvent(btnDecrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(2);
|
||||
expect(input.value).to.be.equal('2');
|
||||
|
||||
setTimeout(_ => {
|
||||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(2);
|
||||
expect(input.value).to.be.equal('2');
|
||||
done();
|
||||
}, 100);
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
it('step', done => {
|
||||
vm = createVue({
|
||||
|
@ -134,19 +126,19 @@ describe('InputNumber', () => {
|
|||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(8.2);
|
||||
expect(input.value).to.be.equal('8.2');
|
||||
|
||||
triggerEvent(btnDecrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(5);
|
||||
expect(input.value).to.be.equal('5');
|
||||
done();
|
||||
}, 100);
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
it('min', done => {
|
||||
vm = createVue({
|
||||
|
@ -181,11 +173,11 @@ describe('InputNumber', () => {
|
|||
triggerEvent(btnDecrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(6);
|
||||
expect(input.value).to.be.equal('6');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
it('max', done => {
|
||||
vm = createVue({
|
||||
|
@ -220,11 +212,11 @@ describe('InputNumber', () => {
|
|||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
expect(vm.value).to.be.equal(8);
|
||||
expect(input.value).to.be.equal('8');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
it('controls', () => {
|
||||
vm = createVue({
|
||||
|
@ -242,4 +234,30 @@ describe('InputNumber', () => {
|
|||
expect(vm.$el.querySelector('.el-input-number__decrease')).to.not.exist;
|
||||
expect(vm.$el.querySelector('.el-input-number__increase')).to.not.exist;
|
||||
});
|
||||
it('event:change', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-input-number v-model="value" ref="input">
|
||||
</el-input-number>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
value: 1.5
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
|
||||
let btnIncrease = vm.$el.querySelector('.el-input-number__increase');
|
||||
const spy = sinon.spy();
|
||||
|
||||
vm.$refs.input.$on('change', spy);
|
||||
|
||||
triggerEvent(btnIncrease, 'mousedown');
|
||||
triggerEvent(document, 'mouseup');
|
||||
|
||||
vm.$nextTick(_ => {
|
||||
expect(spy.withArgs(2.5, 1.5).calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -104,6 +104,7 @@ describe('Input', () => {
|
|||
}, true);
|
||||
expect(vm.$el.querySelector('.el-textarea__inner').getAttribute('rows')).to.be.equal('3');
|
||||
});
|
||||
|
||||
it('autosize', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
|
@ -143,4 +144,57 @@ describe('Input', () => {
|
|||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
describe('Input Events', () => {
|
||||
it('event:focus & blur', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-input
|
||||
ref="input"
|
||||
placeholder="请输入内容"
|
||||
value="input">
|
||||
</el-input>
|
||||
`
|
||||
}, true);
|
||||
|
||||
const spyFocus = sinon.spy();
|
||||
const spyBlur = sinon.spy();
|
||||
|
||||
vm.$refs.input.$on('focus', spyFocus);
|
||||
vm.$refs.input.$on('blur', spyBlur);
|
||||
vm.$el.querySelector('input').focus();
|
||||
vm.$el.querySelector('input').blur();
|
||||
|
||||
vm.$nextTick(_ => {
|
||||
expect(spyFocus.calledOnce).to.be.true;
|
||||
expect(spyBlur.calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('event:change', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-input
|
||||
ref="input"
|
||||
placeholder="请输入内容"
|
||||
:value="input">
|
||||
</el-input>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
input: 'a'
|
||||
};
|
||||
}
|
||||
}, true);
|
||||
|
||||
const spy = sinon.spy();
|
||||
vm.$refs.input.$on('change', spy);
|
||||
vm.input = 'b';
|
||||
|
||||
vm.$nextTick(_ => {
|
||||
expect(spy.withArgs('b').calledOnce).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -40,6 +40,18 @@ describe('Pagination', () => {
|
|||
expect(elm.querySelector('.el-pagination__total')).to.not.exist;
|
||||
});
|
||||
|
||||
it('layout: all in right, need clear float', () => {
|
||||
vm = createTest(Pagination, {
|
||||
layout: '->, prev, pager, next',
|
||||
total: 100
|
||||
}, true);
|
||||
const elm = vm.$el;
|
||||
let right_div = elm.querySelector('.el-pagination__rightwrapper');
|
||||
expect(elm.clientHeight > 0 && right_div.clientHeight > 0).to.equal(true);
|
||||
// elm 将来 padding 可能会变化, 所以使用 >= 来判定
|
||||
expect(elm.clientHeight >= right_div.clientHeight).to.equal(true);
|
||||
});
|
||||
|
||||
it('custom slot', () => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
|
|
|
@ -8,11 +8,11 @@ const toArray = function(obj) {
|
|||
|
||||
const getTestData = function() {
|
||||
return [
|
||||
{ name: 'Toy Story', release: '1995-11-22', director: 'John Lasseter', runtime: 80 },
|
||||
{ name: 'A Bug\'s Life', release: '1998-11-25', director: 'John Lasseter', runtime: 95 },
|
||||
{ name: 'Toy Story 2', release: '1999-11-24', director: 'John Lasseter', runtime: 92 },
|
||||
{ name: 'Monsters, Inc.', release: '2001-11-2', director: 'Peter Docter', runtime: 92 },
|
||||
{ name: 'Finding Nemo', release: '2003-5-30', director: 'Andrew Stanton', runtime: 100 }
|
||||
{ id: 1, name: 'Toy Story', release: '1995-11-22', director: 'John Lasseter', runtime: 80 },
|
||||
{ id: 2, name: 'A Bug\'s Life', release: '1998-11-25', director: 'John Lasseter', runtime: 95 },
|
||||
{ id: 3, name: 'Toy Story 2', release: '1999-11-24', director: 'John Lasseter', runtime: 92 },
|
||||
{ id: 4, name: 'Monsters, Inc.', release: '2001-11-2', director: 'Peter Docter', runtime: 92 },
|
||||
{ id: 5, name: 'Finding Nemo', release: '2003-5-30', director: 'Andrew Stanton', runtime: 100 }
|
||||
];
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,7 @@ describe('Table', () => {
|
|||
const vm = createVue({
|
||||
template: `
|
||||
<el-table :data="testData">
|
||||
<el-table-column prop="id" />
|
||||
<el-table-column prop="name" label="片名" />
|
||||
<el-table-column prop="release" label="发行日期" />
|
||||
<el-table-column prop="director" label="导演" />
|
||||
|
@ -843,12 +844,12 @@ describe('Table', () => {
|
|||
vm.$el.querySelectorAll('.el-checkbox')[1].click();
|
||||
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(1);
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__input.is-checked')).to.length(1);
|
||||
// go to second page
|
||||
vm.testData = getData(1);
|
||||
setTimeout(_ => {
|
||||
// expect no checked
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(0);
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__input.is-checked')).to.length(0);
|
||||
// click first checkbox
|
||||
vm.$el.querySelectorAll('.el-checkbox')[1].click();
|
||||
vm.$el.querySelectorAll('.el-checkbox')[2].click();
|
||||
|
@ -856,11 +857,11 @@ describe('Table', () => {
|
|||
// back first page
|
||||
vm.testData = getData();
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(1);
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__input.is-checked')).to.length(1);
|
||||
// clear
|
||||
vm.$refs.table.clearSelection();
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__inner.is-checked')).to.length(0);
|
||||
expect(vm.$el.querySelectorAll('.el-checkbox__input.is-checked')).to.length(0);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
|
@ -957,6 +958,90 @@ describe('Table', () => {
|
|||
}, DELAY);
|
||||
});
|
||||
});
|
||||
|
||||
describe('= expand', () => {
|
||||
const createInstance = function(extra) {
|
||||
extra = extra || '';
|
||||
return createVue({
|
||||
template: `
|
||||
<el-table row-key="id" :data="testData" @expand="handleExpand" ${extra}>
|
||||
<el-table-column type="expand" inline-template>
|
||||
<div>{{row.name}}</div>
|
||||
</el-table-column>
|
||||
<el-table-column prop="release" label="release" />
|
||||
<el-table-column prop="director" label="director" />
|
||||
<el-table-column prop="runtime" label="runtime" />
|
||||
</el-table>
|
||||
`,
|
||||
|
||||
created() {
|
||||
this.testData = getTestData();
|
||||
},
|
||||
|
||||
data() {
|
||||
return { expandCount: 0, expandRowKeys: [] };
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleExpand() {
|
||||
this.expandCount++;
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
};
|
||||
|
||||
it('works', done => {
|
||||
const vm = createInstance();
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('td.el-table__expand-column').length).to.equal(5);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('should expand when click icon', done => {
|
||||
const vm = createInstance();
|
||||
setTimeout(_ => {
|
||||
vm.$el.querySelector('td.el-table__expand-column .el-table__expand-icon').click();
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(1);
|
||||
expect(vm.expandCount).to.equal(1);
|
||||
vm.$el.querySelector('td.el-table__expand-column .el-table__expand-icon').click();
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(0);
|
||||
expect(vm.expandCount).to.equal(2);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('should set expanded rows using expandRowKeys', done => {
|
||||
const vm = createInstance(':expand-row-keys="expandRowKeys"');
|
||||
setTimeout(_ => {
|
||||
vm.expandRowKeys = [1, 3];
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(2);
|
||||
vm.expandRowKeys = [2];
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(1);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('should default-expand-all when default-expand-all is true', done => {
|
||||
const vm = createInstance('default-expand-all');
|
||||
setTimeout(_ => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__expanded-cell').length).to.equal(5);
|
||||
destroyVM(vm);
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortable', () => {
|
||||
|
@ -981,7 +1066,7 @@ describe('Table', () => {
|
|||
});
|
||||
|
||||
setTimeout(_ => {
|
||||
const elm = vm.$el.querySelector('.caret-wrapper');
|
||||
const elm = vm.$el.querySelector('.caret-wrapper > .ascending');
|
||||
|
||||
elm.click();
|
||||
setTimeout(_ => {
|
||||
|
@ -1003,7 +1088,7 @@ describe('Table', () => {
|
|||
}
|
||||
}, '@sort-change="sortChange"');
|
||||
setTimeout(_ => {
|
||||
const elm = vm.$el.querySelector('.caret-wrapper');
|
||||
const elm = vm.$el.querySelector('.caret-wrapper > .ascending');
|
||||
|
||||
elm.click();
|
||||
setTimeout(_ => {
|
||||
|
@ -1019,7 +1104,7 @@ describe('Table', () => {
|
|||
const vm = createTable('', '', '', 'sortable');
|
||||
|
||||
it('ascending', done => {
|
||||
const elm = vm.$el.querySelector('.caret-wrapper');
|
||||
const elm = vm.$el.querySelector('.caret-wrapper > .ascending');
|
||||
|
||||
elm.click();
|
||||
setTimeout(_ => {
|
||||
|
@ -1031,7 +1116,7 @@ describe('Table', () => {
|
|||
});
|
||||
|
||||
it('descending', done => {
|
||||
const elm = vm.$el.querySelector('.caret-wrapper');
|
||||
const elm = vm.$el.querySelector('.caret-wrapper > .descending');
|
||||
|
||||
elm.click();
|
||||
setTimeout(_ => {
|
||||
|
@ -1215,6 +1300,43 @@ describe('Table', () => {
|
|||
}, DELAY);
|
||||
});
|
||||
|
||||
it('header-align', (done) => {
|
||||
const vm = createVue({
|
||||
template: `
|
||||
<el-table :data="testData">
|
||||
<el-table-column prop="name" :align="align" :header-align="headerAlign"/>
|
||||
</el-table>
|
||||
`,
|
||||
|
||||
data() {
|
||||
return {
|
||||
align: 'left',
|
||||
headerAlign: null
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.testData = getTestData();
|
||||
}
|
||||
}, true);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__header th.is-left').length > 0).to.be.true;
|
||||
expect(vm.$el.querySelectorAll('.el-table__header td.is-center').length === 0).to.be.true;
|
||||
vm.align = 'right';
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__header th.is-right').length > 0).to.be.true;
|
||||
expect(vm.$el.querySelectorAll('.el-table__header td.is-center').length === 0).to.be.true;
|
||||
vm.headerAlign = 'center';
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelectorAll('.el-table__header th.is-right').length === 0).to.be.true;
|
||||
expect(vm.$el.querySelectorAll('.el-table__header td.is-center').length > 0).to.be.true;
|
||||
});
|
||||
});
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
it('width', (done) => {
|
||||
const vm = createVue({
|
||||
template: `
|
||||
|
|
|
@ -188,7 +188,7 @@ describe('Tabs', () => {
|
|||
it('closable edge', done => {
|
||||
vm = createVue({
|
||||
template: `
|
||||
<el-tabs type="card" :closable="true">
|
||||
<el-tabs type="card" :closable="true" ref="tabs">
|
||||
<el-tab-pane label="用户管理">A</el-tab-pane>
|
||||
<el-tab-pane label="配置管理">B</el-tab-pane>
|
||||
<el-tab-pane label="角色管理">C</el-tab-pane>
|
||||
|
@ -199,7 +199,7 @@ describe('Tabs', () => {
|
|||
|
||||
let tabList = vm.$el.querySelector('.el-tabs__header').children;
|
||||
let paneList = vm.$el.querySelector('.el-tabs__content').children;
|
||||
setTimeout(_ => {
|
||||
vm.$nextTick(_ => {
|
||||
tabList[0].querySelector('.el-icon-close').click();
|
||||
vm.$nextTick(_ => {
|
||||
expect(tabList.length).to.be.equal(3);
|
||||
|
@ -209,16 +209,16 @@ describe('Tabs', () => {
|
|||
|
||||
tabList[2].click();
|
||||
tabList[2].querySelector('.el-icon-close').click();
|
||||
vm.$nextTick(_ => {
|
||||
setTimeout(_ => {
|
||||
expect(tabList.length).to.be.equal(2);
|
||||
expect(paneList.length).to.be.equal(2);
|
||||
expect(tabList[1].classList.contains('is-active')).to.be.true;
|
||||
expect(tabList[1].innerText.trim()).to.be.equal('角色管理');
|
||||
expect(paneList[1].innerText.trim()).to.be.equal('C');
|
||||
done();
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
it('tab title render function', done => {
|
||||
vm = createVue({
|
||||
|
|
Loading…
Reference in New Issue