Tabs: add before-leave hook (#11259)

* Tabs: add before-leave hook

* Tabs: update tabs.d.ts
pull/11275/head
Jikkai Xiao 2018-05-21 19:10:49 +08:00 committed by 杨奕
parent f5c113da80
commit 48c40ffa0a
6 changed files with 79 additions and 3 deletions

View File

@ -376,6 +376,7 @@ Only card type Tabs support addable & closeable.
| editable | whether Tab is addable and closable | boolean | — | false | | editable | whether Tab is addable and closable | boolean | — | false |
| value | name of the selected tab | string | — | name of first tab | | value | name of the selected tab | string | — | name of first tab |
| tab-position | position of tabs | string | top/right/bottom/left | top | | tab-position | position of tabs | string | top/right/bottom/left | top |
| before-leave | hook function before switching tab. If `false` is returned or a `Promise` is returned and then is rejected, switching will be prevented | function | — | — |
### Tabs Events ### Tabs Events
| Event Name | Description | Parameters | | Event Name | Description | Parameters |

View File

@ -376,6 +376,7 @@ Solo las pestañas de tipo tarjeta soportan adición y cierre.
| editable | si la Pestaña es añadible y cerrable | boolean | — | false | | editable | si la Pestaña es añadible y cerrable | boolean | — | false |
| value | nombre de la pestaña seleccionada | string | — | nombre de la primer pestaña | | value | nombre de la pestaña seleccionada | string | — | nombre de la primer pestaña |
| tab-position | posición de tabulación | string | top/right/bottom/left | top | | tab-position | posición de tabulación | string | top/right/bottom/left | top |
| before-leave | hook function before switching tab. If `false` is returned or a `Promise` is returned and then is rejected, switching will be prevented | function | — | — |
### Eventos de Pestañas ### Eventos de Pestañas
| Nombre de Evento | Descripción | Parámetros | | Nombre de Evento | Descripción | Parámetros |

View File

@ -374,6 +374,7 @@
| editable | 标签是否同时可增加和关闭 | boolean | — | false | | editable | 标签是否同时可增加和关闭 | boolean | — | false |
| value | 绑定值,选中选项卡的 name | string | — | 第一个选项卡的 name | | value | 绑定值,选中选项卡的 name | string | — | 第一个选项卡的 name |
| tab-position | 选项卡所在位置 | string | top/right/bottom/left | top | | tab-position | 选项卡所在位置 | string | top/right/bottom/left | top |
| before-leave | 切换标签之前的钩子,若返回 false 或者返回 Promise 且被 reject则阻止切换。 | function | — | — |
### Tabs Events ### Tabs Events
| 事件名称 | 说明 | 回调参数 | | 事件名称 | 说明 | 回调参数 |

View File

@ -18,7 +18,8 @@
tabPosition: { tabPosition: {
type: String, type: String,
default: 'top' default: 'top'
} },
beforeLeave: Function
}, },
provide() { provide() {
@ -67,8 +68,22 @@
this.$emit('tab-add'); this.$emit('tab-add');
}, },
setCurrentName(value) { setCurrentName(value) {
const changeCurrentName = () => {
this.currentName = value; this.currentName = value;
this.$emit('input', value); this.$emit('input', value);
};
if (this.currentName !== value && this.beforeLeave) {
const before = this.beforeLeave();
if (before && before.then) {
before.then(() => {
changeCurrentName();
});
} else if (before !== false) {
changeCurrentName();
}
} else {
changeCurrentName();
}
}, },
addPanes(item) { addPanes(item) {
const index = this.$slots.default.filter(item => { const index = this.$slots.default.filter(item => {

View File

@ -2,6 +2,20 @@ import { createVue, destroyVM } from '../util';
describe('Tabs', () => { describe('Tabs', () => {
let vm; let vm;
let hasPromise = true;
before(() => {
if (!window.Promise) {
hasPromise = false;
window.Promise = require('es6-promise').Promise;
}
});
after(() => {
if (!hasPromise) {
window.Promise = undefined;
}
});
afterEach(() => { afterEach(() => {
destroyVM(vm); destroyVM(vm);
}); });
@ -457,4 +471,45 @@ describe('Tabs', () => {
}); });
}, 100); }, 100);
}); });
it('before leave', done => {
vm = createVue({
template: `
<el-tabs ref="tabs" v-model="activeName" :before-leave="beforeLeave">
<el-tab-pane name="tab-A" label="用户管理">A</el-tab-pane>
<el-tab-pane name="tab-B" label="配置管理">B</el-tab-pane>
<el-tab-pane name="tab-C" label="角色管理">C</el-tab-pane>
<el-tab-pane name="tab-D" label="定时任务补偿">D</el-tab-pane>
</el-tabs>
`,
data() {
return {
activeName: 'tab-B'
};
},
methods: {
beforeLeave() {
return new window.Promise((resolve, reject) => {
reject();
});
}
}
}, true);
setTimeout(_ => {
const paneList = vm.$el.querySelector('.el-tabs__content').children;
const tabList = vm.$refs.tabs.$refs.nav.$refs.tabs;
expect(tabList[1].classList.contains('is-active')).to.be.true;
expect(paneList[1].style.display).to.not.ok;
tabList[3].click();
vm.$nextTick(_ => {
setTimeout(() => {
expect(tabList[1].classList.contains('is-active')).to.be.true;
expect(paneList[1].style.display).to.not.ok;
expect(vm.activeName === 'tab-B');
done();
}, 200);
});
}, 100);
});
}); });

3
types/tabs.d.ts vendored
View File

@ -22,4 +22,7 @@ export declare class ElTabs extends ElementUIComponent {
/** Position of tabs */ /** Position of tabs */
tabPosition: TabPosition tabPosition: TabPosition
/** Hook function before switching tab. If false or a Promise is returned and then is rejected, switching will be prevented */
beforeLeave: () => boolean | Promise<any>
} }