Merge pull request #824 from furybean/table-current-row

Table: add current-change event & highlight-current-row prop.
This commit is contained in:
杨奕 2016-11-04 17:38:07 +08:00 committed by GitHub
commit f67104f28e
7 changed files with 112 additions and 7 deletions

View File

@ -13,6 +13,7 @@
- 修复 Slider 在 Form 中的显示问题
- 修复 Upload 在 onSuccess、onError 钩子无法拿到服务端返回信息的问题
- 改善 tabs 现在支持动态更新
- Table 新增 highlightCurrentRow 属性、新增 current-change 事件
#### 非兼容性更新

View File

@ -898,6 +898,7 @@
| stripe | 是否为斑马纹 table | boolean | — | false |
| border | 是否带有纵向边框 | boolean | — | false |
| fit | 列的宽度是否自撑开 | boolean | — | true |
| highlight-current-row | 是否要高亮当前行 | boolean | - | false |
| row-class-name | 行的 className 的回调。 | Function(row, index) | - | - |
| row-key | 行数据的 Key用来优化 Table 的渲染;在使用 reserve-selection 功能的情况下,该属性是必填的 | Function(row), String | - | - |
@ -912,6 +913,7 @@
| cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
| row-click | 当某一行被点击时会触发该事件 | row, event |
| sort-change | 当表格的排序条件发生变化的时候会触发该事件 | { column, prop, order } |
| current-change | 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性 | { column, prop, order } |
### Table Methods
| 方法名 | 说明 | 参数 |

View File

@ -9,7 +9,8 @@ export default {
required: true
},
rowClassName: [String, Function],
fixed: String
fixed: String,
highlight: Boolean
},
render(h) {
@ -115,6 +116,11 @@ export default {
classes.push(rowClassName.apply(null, [row, index]) || '');
}
const currentRow = this.store.states.currentRow;
if (this.highlight && currentRow === row) {
classes.push('current-row');
}
return classes.join(' ');
},
@ -161,6 +167,8 @@ export default {
}
}
this.store.commit('setCurrentRow', row);
table.$emit('row-click', row, event);
},

View File

@ -74,6 +74,7 @@ const TableStore = function(table, initialState = {}) {
selection: [],
reserveSelection: false,
selectable: null,
currentRow: null,
hoverRow: null,
filters: {}
};
@ -89,6 +90,9 @@ TableStore.prototype.mutations = {
setData(states, data) {
states._data = data;
states.data = sortData((data || []), states);
this.updateCurrentRow();
const selection = states.selection;
if (!states.reserveSelection) {
@ -186,13 +190,23 @@ TableStore.prototype.mutations = {
states.hoverRow = row;
},
setCurrentRow(states, row) {
const oldCurrentRow = states.currentRow;
states.currentRow = row;
if (oldCurrentRow !== row) {
this.table.$emit('current-change', row, oldCurrentRow);
}
},
rowSelectedChanged(states, row) {
const changed = toggleRowSelection(states, row);
const selection = states.selection;
if (changed) {
this.table.$emit('selection-change', selection);
this.table.$emit('select', selection, row);
const table = this.table;
table.$emit('selection-change', selection);
table.$emit('select', selection, row);
}
this.updateAllSelected();
@ -216,10 +230,11 @@ TableStore.prototype.mutations = {
}
});
const table = this.table;
if (selectionChanged) {
this.table.$emit('selection-change', selection);
table.$emit('selection-change', selection);
}
this.table.$emit('select-all', selection);
table.$emit('select-all', selection);
states.isAllSelected = value;
})
};
@ -295,6 +310,21 @@ TableStore.prototype.scheduleLayout = function() {
this.table.debouncedLayout();
};
TableStore.prototype.updateCurrentRow = function() {
const states = this.states;
const table = this.table;
const data = states.data || [];
const oldCurrentRow = states.currentRow;
if (data.indexOf(oldCurrentRow) === -1) {
states.currentRow = null;
if (states.currentRow !== oldCurrentRow) {
table.$emit('current-change', null, oldCurrentRow);
}
}
};
TableStore.prototype.commit = function(name, ...args) {
const mutations = this.mutations;
if (mutations[name]) {

View File

@ -17,6 +17,7 @@
:store="store"
:layout="layout"
:row-class-name="rowClassName"
:highlight="highlightCurrentRow"
:style="{ width: layout.bodyWidth ? layout.bodyWidth - (layout.scrollY ? layout.gutterWidth : 0 ) + 'px' : '' }">
</table-body>
<div class="el-table__empty-block" v-if="!data || data.length === 0">
@ -47,6 +48,7 @@
fixed="left"
:store="store"
:layout="layout"
:highlight="highlightCurrentRow"
:row-class-name="rowClassName"
:style="{ width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' }">
</table-body>
@ -78,6 +80,7 @@
:store="store"
:layout="layout"
:row-class-name="rowClassName"
:highlight="highlightCurrentRow"
:style="{ width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' }">
</table-body>
</div>
@ -130,6 +133,8 @@
rowClassName: [String, Function],
highlightCurrentRow: Boolean,
emptyText: {
type: String,
default: $t('el.table.emptyText')

View File

@ -330,7 +330,7 @@
background-color: #eff2f7;
}
tr.current-row {
tr.current-row td {
background: #eff7ff;
}
}

View File

@ -261,7 +261,7 @@ describe('Table', () => {
},
data() {
return { result: '' };
return { result: '', testData: this.testData };
}
}, true);
};
@ -358,6 +358,32 @@ describe('Table', () => {
done();
}, DELAY);
});
it('current-change', done => {
const vm = createTable('current-change');
setTimeout(_ => {
const cell = vm.$el.querySelectorAll('.el-table__body .cell')[2]; // first row
triggerEvent(cell.parentNode.parentNode, 'click');
expect(vm.result).to.length(2); // currentRow, oldCurrentRow
expect(vm.result[0]).to.have.property('name').to.equal(getTestData()[0].name);
expect(vm.result[1]).to.equal(null);
// clear data => current-change should fire again.
const oldRow = vm.result[0];
vm.testData = [];
setTimeout(() => {
expect(vm.result).to.length(2); // currentRow, oldCurrentRow
expect(vm.result[0]).to.equal(null);
expect(vm.result[1]).to.equal(oldRow);
destroyVM(vm);
done();
}, DELAY);
}, DELAY);
});
});
describe('column attributes', () => {
@ -825,4 +851,37 @@ describe('Table', () => {
}, DELAY);
}, DELAY);
});
it('highlight-current-row', done => {
const vm = createVue({
template: `
<el-table :data="testData" highlight-current-row>
<el-table-column prop="name" label="片名" />
<el-table-column prop="release" label="发行日期" />
<el-table-column prop="director" label="导演" />
<el-table-column prop="runtime" label="时长(分)" />
</el-table>
`,
created() {
this.testData = getTestData();
}
}, true);
setTimeout(_ => {
const tr = vm.$el.querySelector('.el-table__body-wrapper tbody tr');
triggerEvent(tr, 'click', true, false);
setTimeout(_ => {
expect(tr.classList.contains('current-row')).to.be.true;
const rows = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr');
triggerEvent(rows[2], 'click', true, false);
setTimeout(_ => {
expect(tr.classList.contains('current-row')).to.be.false;
expect(rows[2].classList.contains('current-row')).to.be.true;
destroyVM(vm);
done();
}, DELAY);
}, DELAY);
}, DELAY);
});
});