| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- <script>
- import TabNav from './tab-nav';
- export default {
- name: 'ElTabs',
- components: {
- TabNav
- },
- props: {
- type: String,
- activeName: String,
- closable: Boolean,
- addable: Boolean,
- value: {},
- editable: Boolean,
- tabPosition: {
- type: String,
- default: 'top'
- },
- beforeLeave: Function,
- stretch: Boolean
- },
- provide() {
- return {
- rootTabs: this
- };
- },
- data() {
- return {
- currentName: this.value || this.activeName,
- panes: []
- };
- },
- watch: {
- activeName(value) {
- this.setCurrentName(value);
- },
- value(value) {
- this.setCurrentName(value);
- },
- currentName(value) {
- if (this.$refs.nav) {
- this.$nextTick(() => {
- this.$refs.nav.$nextTick(_ => {
- this.$refs.nav.scrollToActiveTab();
- });
- });
- }
- }
- },
- methods: {
- calcPaneInstances(isForceUpdate = false) {
- if (this.$slots.default) {
- const paneSlots = this.$slots.default.filter(vnode => vnode.tag &&
- vnode.componentOptions && vnode.componentOptions.Ctor.options.name === 'ElTabPane');
- // update indeed
- const panes = paneSlots.map(({ componentInstance }) => componentInstance);
- const panesChanged = !(panes.length === this.panes.length && panes.every((pane, index) => pane === this.panes[index]));
- if (isForceUpdate || panesChanged) {
- this.panes = panes;
- }
- } else if (this.panes.length !== 0) {
- this.panes = [];
- }
- },
- handleTabClick(tab, tabName, event) {
- if (tab.disabled) return;
- this.setCurrentName(tabName);
- this.$emit('tab-click', tab, event);
- },
- handleTabRemove(pane, ev) {
- if (pane.disabled) return;
- ev.stopPropagation();
- this.$emit('edit', pane.name, 'remove');
- this.$emit('tab-remove', pane.name);
- },
- handleTabAdd() {
- this.$emit('edit', null, 'add');
- this.$emit('tab-add');
- },
- setCurrentName(value) {
- const changeCurrentName = () => {
- this.currentName = value;
- this.$emit('input', value);
- };
- if (this.currentName !== value && this.beforeLeave) {
- const before = this.beforeLeave(value, this.currentName);
- if (before && before.then) {
- before
- .then(() => {
- changeCurrentName();
- this.$refs.nav && this.$refs.nav.removeFocus();
- }, () => {
- // https://github.com/ElemeFE/element/pull/14816
- // ignore promise rejection in `before-leave` hook
- });
- } else if (before !== false) {
- changeCurrentName();
- }
- } else {
- changeCurrentName();
- }
- }
- },
- render(h) {
- let {
- type,
- handleTabClick,
- handleTabRemove,
- handleTabAdd,
- currentName,
- panes,
- editable,
- addable,
- tabPosition,
- stretch
- } = this;
- const newButton = editable || addable
- ? (
- <span
- class="el-tabs__new-tab"
- on-click={ handleTabAdd }
- tabindex="0"
- on-keydown={ (ev) => { if (ev.keyCode === 13) { handleTabAdd(); }} }
- >
- <i class="el-icon-plus"></i>
- </span>
- )
- : null;
- const navData = {
- props: {
- currentName,
- onTabClick: handleTabClick,
- onTabRemove: handleTabRemove,
- editable,
- type,
- panes,
- stretch
- },
- ref: 'nav'
- };
- const header = (
- <div class={['el-tabs__header', `is-${tabPosition}`]}>
- {newButton}
- <tab-nav { ...navData }></tab-nav>
- </div>
- );
- const panels = (
- <div class="el-tabs__content">
- {this.$slots.default}
- </div>
- );
- return (
- <div class={{
- 'el-tabs': true,
- 'el-tabs--card': type === 'card',
- [`el-tabs--${tabPosition}`]: true,
- 'el-tabs--border-card': type === 'border-card'
- }}>
- { tabPosition !== 'bottom' ? [header, panels] : [panels, header] }
- </div>
- );
- },
-
- created() {
- if (!this.currentName) {
- this.setCurrentName('0');
- }
- this.$on('tab-nav-update', this.calcPaneInstances.bind(null, true));
- },
- mounted() {
- this.calcPaneInstances();
- },
- updated() {
- this.calcPaneInstances();
- }
- };
- </script>
|