diff --git a/packages/tabs/src/tab-pane.vue b/packages/tabs/src/tab-pane.vue index 7c95c2538..9ec24bee5 100644 --- a/packages/tabs/src/tab-pane.vue +++ b/packages/tabs/src/tab-pane.vue @@ -7,7 +7,8 @@ type: String, required: true }, - name: String + name: String, + closable: Boolean }, data() { @@ -17,14 +18,24 @@ paneStyle: { position: 'relative' }, + isClosable: null, index: '' }; }, 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: { @@ -34,9 +45,13 @@ }, destroyed() { - if (this.$el) { + 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: { @@ -46,6 +61,9 @@ this.index = val; } }, + closable(val) { + this.isClosable = val; + }, '$parent.currentName'(newValue, oldValue) { if (this.index === newValue) { this.transition = newValue > oldValue ? 'slideInRight' : 'slideInLeft'; diff --git a/packages/tabs/src/tabs.vue b/packages/tabs/src/tabs.vue index 85a24ed11..9ee0e38bf 100644 --- a/packages/tabs/src/tabs.vue +++ b/packages/tabs/src/tabs.vue @@ -14,7 +14,8 @@ return { children: null, activeTab: null, - currentName: 0 + currentName: 0, + panes: [] }; }, @@ -80,7 +81,7 @@ render(h) { let { type, - closable, + panes, // eslint-disable-line handleTabRemove, handleTabClick, currentName @@ -103,14 +104,14 @@ 'el-tabs__item': true, 'is-active': currentName === tab.index, 'is-disabled': tab.disabled, - 'is-closable': closable + 'is-closable': tab.isClosable }, ref: 'tabs', refInFor: true, on: { click: (ev) => { handleTabClick(tab, ev); } } }, [ tab.label, - closable ? btnClose : null, + tab.isClosable ? btnClose : null, index === 0 ? activeBar : null ]); return _tab; diff --git a/packages/theme-default/src/tabs.css b/packages/theme-default/src/tabs.css index f4bb950e4..61dd2e610 100644 --- a/packages/theme-default/src/tabs.css +++ b/packages/theme-default/src/tabs.css @@ -35,6 +35,22 @@ margin-bottom: -1px; position: relative; + & .el-icon-close { + border-radius: 50%; + text-align: center; + transition: all .3s cubic-bezier(.645,.045,.355,1); + margin-left: 5px; + &:before { + transform: scale(.7, .7); + display: inline-block; + } + + &:hover { + background-color: #99a9bf; + color: #fff; + } + } + @when active { color: var(--color-primary); } @@ -53,29 +69,16 @@ display: none; } & .el-tabs__item .el-icon-close { + position: relative; font-size: 12px; + width: 0; + height: 14px; vertical-align: middle; line-height: 15px; overflow: hidden; - width: 0; - height: 14px; - border-radius: 50%; - text-align: center; - transform-origin: 100% 50%; - transition: all .3s cubic-bezier(.645,.045,.355,1); - position: relative; top: -1px; right: -2px; - - &:before { - transform: scale(.7, .7); - display: inline-block; - } - - &:hover { - background-color: #99a9bf; - color: #fff; - } + transform-origin: 100% 50%; } .el-tabs__item { border: 1px solid transparent; diff --git a/test/unit/specs/tabs.spec.js b/test/unit/specs/tabs.spec.js index 6a94f0bfe..e7aa5ebdb 100644 --- a/test/unit/specs/tabs.spec.js +++ b/test/unit/specs/tabs.spec.js @@ -100,6 +100,44 @@ describe('Tabs', () => { expect(vm.$el.classList.contains('el-tabs--border-card')).to.be.true; }); + it('dynamic', (done) => { + vm = createVue({ + template: ` + + Test Content + + `, + data() { + return { + tabs: [{ + label: 'tab1', + name: 'tab1' + }, { + label: 'tab2', + name: 'tab2' + }, { + label: 'tab3', + name: 'tab3' + }, { + label: 'tab4', + name: 'tab4' + }] + }; + } + }, true); + + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-tab-pane').length).to.equal(4); + vm.tabs.push({ + label: 'tab5', + name: 'tab5' + }); + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-tab-pane').length).to.equal(5); + done(); + }); + }, 100); + }); it('closable', done => { vm = createVue({ template: ` @@ -130,6 +168,23 @@ describe('Tabs', () => { }); }, 100); }); + it('closable in tab-pane', (done) => { + vm = createVue({ + template: ` + + A + B + C + D + + ` + }, true); + + setTimeout(() => { + expect(vm.$el.querySelectorAll('.el-icon-close').length).to.equal(2); + done(); + }, 100); + }); it('closable edge', done => { vm = createVue({ template: `