fix tab-bar initial status bug

pull/2212/head
baiyaaaaa 2017-01-04 12:32:00 +08:00 committed by 杨奕
parent 7562e82bf6
commit 0c0f2527e3
6 changed files with 78 additions and 50 deletions

View File

@ -2,7 +2,7 @@
export default { export default {
data() { data() {
return { return {
activeName: 'first', activeName: 'second',
activeName2: 'first', activeName2: 'first',
tabs: [{ tabs: [{
title: 'Tab 1', title: 'Tab 1',
@ -50,7 +50,7 @@
export default { export default {
data() { data() {
return { return {
activeName: 'first' activeName: 'second'
}; };
}, },
methods: { methods: {

View File

@ -0,0 +1,39 @@
<template>
<div class="el-tabs__active-bar" :style="barStyle"></div>
</template>
<script>
export default {
props: {
tabs: Array
},
computed: {
barStyle: {
cache: false,
get() {
if (!this.$parent.$refs.tabs) return {};
let style = {};
let offset = 0;
let tabWidth = 0;
this.tabs.every((tab, index) => {
let $el = this.$parent.$refs.tabs[index];
if (!$el) { return false; }
if (!tab.active) {
offset += $el.clientWidth;
return true;
} else {
tabWidth = $el.clientWidth;
return false;
}
});
style.width = tabWidth + 'px';
style.transform = `translateX(${offset}px)`;
return style;
}
}
}
};
</script>

View File

@ -9,6 +9,8 @@
module.exports = { module.exports = {
name: 'ElTabPane', name: 'ElTabPane',
componentName: 'ElTabPane',
props: { props: {
label: String, label: String,
labelContent: Function, labelContent: Function,

View File

@ -1,7 +1,12 @@
<script> <script>
import TabBar from './tab-bar';
module.exports = { module.exports = {
name: 'ElTabs', name: 'ElTabs',
components: {
TabBar
},
props: { props: {
type: String, type: String,
activeName: String, activeName: String,
@ -29,10 +34,16 @@
}, },
computed: { computed: {
tabPanes: {
cache: false,
get() {
if (!this.$children) return [];
return this.$children.filter(item => item.$options.componentName === 'ElTabPane');
}
},
currentTab() { currentTab() {
if (!this.$children) return;
let result; let result;
this.$children.forEach(tab => { this.tabPanes.forEach(tab => {
if (this.currentName === (tab.name || tab.index)) { if (this.currentName === (tab.name || tab.index)) {
result = tab; result = tab;
} }
@ -44,7 +55,7 @@
methods: { methods: {
handleTabRemove(tab, event) { handleTabRemove(tab, event) {
event.stopPropagation(); event.stopPropagation();
const tabs = this.$children; const tabs = this.tabPanes;
const currentTab = this.currentTab; const currentTab = this.currentTab;
let index = tabs.indexOf(tab); let index = tabs.indexOf(tab);
@ -55,6 +66,7 @@
this.$nextTick(_ => { this.$nextTick(_ => {
if (tab.active) { if (tab.active) {
const tabs = this.tabPanes;
let nextChild = tabs[index]; let nextChild = tabs[index];
let prevChild = tabs[index - 1]; let prevChild = tabs[index - 1];
let nextActiveTab = nextChild || prevChild || null; let nextActiveTab = nextChild || prevChild || null;
@ -86,35 +98,11 @@
type, type,
handleTabRemove, handleTabRemove,
handleTabClick, handleTabClick,
currentName currentName,
tabPanes
} = this; } = this;
const getBarStyle = () => { const tabs = this._l(tabPanes, (tab, index) => {
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 (!tab.active) {
offset += $el.clientWidth;
return true;
} else {
tabWidth = $el.clientWidth;
return false;
}
});
style.width = tabWidth + 'px';
style.transform = `translateX(${offset}px)`;
return style;
};
const tabs = this.$children.map((tab, index) => {
let tabName = tab.name || tab.index || index; let tabName = tab.name || tab.index || index;
if (currentName === undefined && index === 0) { if (currentName === undefined && index === 0) {
this.setCurrentName(tabName); this.setCurrentName(tabName);
@ -122,16 +110,11 @@
tab.index = index; tab.index = index;
const activeBar = !type && index === 0
? <div class="el-tabs__active-bar" style={getBarStyle()}></div>
: null;
const btnClose = tab.isClosable const btnClose = tab.isClosable
? <span class="el-icon-close" on-click={(ev) => { handleTabRemove(tab, ev); }}></span> ? <span class="el-icon-close" on-click={(ev) => { handleTabRemove(tab, ev); }}></span>
: null; : null;
const tabLabelContent = tab.$slots.label || tab.label; const tabLabelContent = tab.$slots.label || tab.label;
return ( return (
<div <div
class={{ class={{
@ -146,10 +129,10 @@
> >
{tabLabelContent} {tabLabelContent}
{btnClose} {btnClose}
{activeBar}
</div> </div>
); );
}); });
return ( return (
<div class={{ <div class={{
'el-tabs': true, 'el-tabs': true,
@ -157,6 +140,7 @@
'el-tabs--border-card': type === 'border-card' 'el-tabs--border-card': type === 'border-card'
}}> }}>
<div class="el-tabs__header"> <div class="el-tabs__header">
{!type ? <tab-bar tabs={tabPanes}></tab-bar> : null}
{tabs} {tabs}
</div> </div>
<div class="el-tabs__content"> <div class="el-tabs__content">

View File

@ -14,7 +14,6 @@
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%;
height: 3px; height: 3px;
background-color: var(--color-primary); background-color: var(--color-primary);
z-index: 1; z-index: 1;

View File

@ -17,13 +17,14 @@ describe('Tabs', () => {
</el-tabs> </el-tabs>
` `
}, true); }, true);
let tabList = vm.$el.querySelector('.el-tabs__header').children;
let paneList = vm.$el.querySelector('.el-tabs__content').children; let paneList = vm.$el.querySelector('.el-tabs__content').children;
let spy = sinon.spy(); let spy = sinon.spy();
vm.$refs.tabs.$on('tab-click', spy); vm.$refs.tabs.$on('tab-click', spy);
setTimeout(_ => { setTimeout(_ => {
const tabList = vm.$refs.tabs.$refs.tabs;
expect(tabList[0].classList.contains('is-active')).to.be.true; expect(tabList[0].classList.contains('is-active')).to.be.true;
expect(paneList[0].style.display).to.not.ok; expect(paneList[0].style.display).to.not.ok;
@ -39,7 +40,7 @@ describe('Tabs', () => {
it('active-name', done => { it('active-name', done => {
vm = createVue({ vm = createVue({
template: ` template: `
<el-tabs :active-name="activeName" @click="handleClick"> <el-tabs ref="tabs" :active-name="activeName" @click="handleClick">
<el-tab-pane name="tab-A" label="用户管理">A</el-tab-pane> <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-B" label="配置管理">B</el-tab-pane>
<el-tab-pane name="tab-C" label="角色管理">C</el-tab-pane> <el-tab-pane name="tab-C" label="角色管理">C</el-tab-pane>
@ -57,10 +58,12 @@ describe('Tabs', () => {
} }
} }
}, true); }, true);
let tabList = vm.$el.querySelector('.el-tabs__header').children;
let paneList = vm.$el.querySelector('.el-tabs__content').children;
setTimeout(_ => { setTimeout(_ => {
const paneList = vm.$el.querySelector('.el-tabs__content').children;
const tabList = vm.$refs.tabs.$refs.tabs;
expect(tabList[1].classList.contains('is-active')).to.be.true; expect(tabList[1].classList.contains('is-active')).to.be.true;
// expect(vm.$el.querySelector('.el-tabs__active-bar'))
expect(paneList[1].style.display).to.not.ok; expect(paneList[1].style.display).to.not.ok;
tabList[3].click(); tabList[3].click();
@ -150,13 +153,13 @@ describe('Tabs', () => {
` `
}, true); }, true);
let tabList = vm.$el.querySelector('.el-tabs__header').children;
let paneList = vm.$el.querySelector('.el-tabs__content').children;
let spy = sinon.spy(); let spy = sinon.spy();
vm.$refs.tabs.$on('tab-remove', spy); vm.$refs.tabs.$on('tab-remove', spy);
setTimeout(_ => { setTimeout(_ => {
const tabList = vm.$refs.tabs.$refs.tabs;
const paneList = vm.$el.querySelector('.el-tabs__content').children;
tabList[1].querySelector('.el-icon-close').click(); tabList[1].querySelector('.el-icon-close').click();
vm.$nextTick(_ => { vm.$nextTick(_ => {
expect(tabList.length).to.be.equal(3); expect(tabList.length).to.be.equal(3);
@ -197,9 +200,10 @@ describe('Tabs', () => {
` `
}, true); }, true);
let tabList = vm.$el.querySelector('.el-tabs__header').children;
let paneList = vm.$el.querySelector('.el-tabs__content').children;
vm.$nextTick(_ => { vm.$nextTick(_ => {
const paneList = vm.$el.querySelector('.el-tabs__content').children;
const tabList = vm.$refs.tabs.$refs.tabs;
tabList[0].querySelector('.el-icon-close').click(); tabList[0].querySelector('.el-icon-close').click();
vm.$nextTick(_ => { vm.$nextTick(_ => {
expect(tabList.length).to.be.equal(3); expect(tabList.length).to.be.equal(3);
@ -223,7 +227,7 @@ describe('Tabs', () => {
it('disabled', done => { it('disabled', done => {
vm = createVue({ vm = createVue({
template: ` template: `
<el-tabs type="card"> <el-tabs type="card" ref="tabs">
<el-tab-pane label="用户管理">A</el-tab-pane> <el-tab-pane label="用户管理">A</el-tab-pane>
<el-tab-pane disabled label="配置管理" ref="disabled">B</el-tab-pane> <el-tab-pane disabled label="配置管理" ref="disabled">B</el-tab-pane>
<el-tab-pane label="角色管理">C</el-tab-pane> <el-tab-pane label="角色管理">C</el-tab-pane>
@ -233,7 +237,7 @@ describe('Tabs', () => {
}, true); }, true);
vm.$nextTick(_ => { vm.$nextTick(_ => {
let tabList = vm.$el.querySelector('.el-tabs__header').children; const tabList = vm.$refs.tabs.$refs.tabs;
tabList[1].click(); tabList[1].click();
vm.$nextTick(_ => { vm.$nextTick(_ => {