Tabs add scroll
This commit is contained in:
parent
2e8add2fb3
commit
be3fbd2499
3 changed files with 161 additions and 6 deletions
|
@ -70,7 +70,7 @@
|
|||
<!--</script>-->
|
||||
|
||||
|
||||
<template>
|
||||
<!-- <template>
|
||||
<Tabs type="card" closable @on-tab-remove="handleTabRemove">
|
||||
<TabPane label="标签一" v-if="tab0">标签一的内容</TabPane>
|
||||
<TabPane label="标签二" v-if="tab1">标签二的内容</TabPane>
|
||||
|
@ -92,4 +92,41 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
</script> -->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Button type="ghost" @click="toFirst" size="small">to first</Button>
|
||||
<Button type="ghost" @click="toLast" size="small">to last</Button>
|
||||
<Tabs type="card" :animated="animated" v-model="activeTab">
|
||||
<TabPane v-for="tab in tabs" :key="tab" :label="'标签' + tab" :name="tab+''" closable>标签{{ tab }}</TabPane>
|
||||
<div slot="extra">
|
||||
<Button type="ghost" @click="handleTabsAdd" size="small">增加</Button>
|
||||
</div>
|
||||
</Tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
tabs: 2,
|
||||
activeTab:"2",
|
||||
animated:true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTabsAdd () {
|
||||
this.tabs ++;
|
||||
this.activeTab = this.tabs + '';
|
||||
},
|
||||
toFirst () {
|
||||
this.activeTab = '1';
|
||||
},
|
||||
toLast () {
|
||||
this.activeTab = this.tabs+'';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div :class="classes">
|
||||
<div :class="[prefixCls + '-bar']">
|
||||
<div :class="[prefixCls + '-nav-right']" v-if="showSlot"><slot name="extra"></slot></div>
|
||||
<div :class="[prefixCls + '-nav-container']">
|
||||
<div :class="[prefixCls + '-nav-wrap']">
|
||||
<div :class="[prefixCls + '-nav-scroll']">
|
||||
<div :class="[prefixCls + '-nav']" ref="nav">
|
||||
<div ref="navWrap" :class="[prefixCls + '-nav-wrap', scrollable ? prefixCls + '-nav-scrollable' : '']" >
|
||||
<span :class="[prefixCls + '-nav-prev', scrollable ? '' : prefixCls + '-nav-scroll-disabled']" @click="scrollPrev"><Icon type="chevron-left"></Icon></span>
|
||||
<span :class="[prefixCls + '-nav-next', scrollable ? '' : prefixCls + '-nav-scroll-disabled']" @click="scrollNext"><Icon type="chevron-right"></Icon></span>
|
||||
<div ref="navScroll" :class="[prefixCls + '-nav-scroll']">
|
||||
<div ref="nav" :class="[prefixCls + '-nav']" class="nav-text" :style="navStyle">
|
||||
<div :class="barClasses" :style="barStyle"></div>
|
||||
<div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
|
||||
<Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
|
||||
|
@ -13,7 +16,6 @@
|
|||
<Icon v-if="showClose(item)" type="ios-close-empty" @click.native.stop="handleRemove(index)"></Icon>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="[prefixCls + '-nav-right']" v-if="showSlot"><slot name="extra"></slot></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,6 +28,7 @@
|
|||
import Render from '../base/render';
|
||||
import { oneOf } from '../../utils/assist';
|
||||
import Emitter from '../../mixins/emitter';
|
||||
import elementResizeDetectorMaker from 'element-resize-detector';
|
||||
|
||||
const prefixCls = 'ivu-tabs';
|
||||
|
||||
|
@ -65,7 +68,11 @@
|
|||
barWidth: 0,
|
||||
barOffset: 0,
|
||||
activeKey: this.value,
|
||||
showSlot: false
|
||||
showSlot: false,
|
||||
navStyle:{
|
||||
transform: ''
|
||||
},
|
||||
scrollable:false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -163,6 +170,7 @@
|
|||
} else {
|
||||
this.barOffset = 0;
|
||||
}
|
||||
this.updateNavScroll();
|
||||
});
|
||||
},
|
||||
updateStatus () {
|
||||
|
@ -222,6 +230,85 @@
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
scrollPrev() {
|
||||
const containerWidth = this.$refs.navScroll.offsetWidth;
|
||||
const currentOffset = this.getCurrentScrollOffset();
|
||||
|
||||
if (!currentOffset) return;
|
||||
|
||||
let newOffset = currentOffset > containerWidth
|
||||
? currentOffset - containerWidth
|
||||
: 0;
|
||||
|
||||
this.setOffset(newOffset);
|
||||
},
|
||||
scrollNext() {
|
||||
const navWidth = this.$refs.nav.offsetWidth;
|
||||
const containerWidth = this.$refs.navScroll.offsetWidth;
|
||||
const currentOffset = this.getCurrentScrollOffset();
|
||||
if (navWidth - currentOffset <= containerWidth) return;
|
||||
|
||||
let newOffset = navWidth - currentOffset > containerWidth * 2
|
||||
? currentOffset + containerWidth
|
||||
: (navWidth - containerWidth);
|
||||
|
||||
this.setOffset(newOffset);
|
||||
},
|
||||
getCurrentScrollOffset() {
|
||||
const { navStyle } = this;
|
||||
return navStyle.transform
|
||||
? Number(navStyle.transform.match(/translateX\(-(\d+(\.\d+)*)px\)/)[1])
|
||||
: 0;
|
||||
},
|
||||
setOffset(value) {
|
||||
this.navStyle.transform = `translateX(-${value}px)`;
|
||||
},
|
||||
scrollToActiveTab() {
|
||||
if (!this.scrollable) return;
|
||||
const nav = this.$refs.nav;
|
||||
const activeTab = this.$el.querySelector(`.${prefixCls}-tab-active`);
|
||||
if(!activeTab) return;
|
||||
|
||||
const navScroll = this.$refs.navScroll;
|
||||
const activeTabBounding = activeTab.getBoundingClientRect();
|
||||
const navScrollBounding = navScroll.getBoundingClientRect();
|
||||
const navBounding = nav.getBoundingClientRect();
|
||||
const currentOffset = this.getCurrentScrollOffset();
|
||||
let newOffset = currentOffset;
|
||||
|
||||
if (navBounding.right < navScrollBounding.right) {
|
||||
newOffset = nav.offsetWidth - navScrollBounding.width;
|
||||
}
|
||||
|
||||
if (activeTabBounding.left < navScrollBounding.left) {
|
||||
newOffset = currentOffset - (navScrollBounding.left - activeTabBounding.left);
|
||||
}else if (activeTabBounding.right > navScrollBounding.right) {
|
||||
newOffset = currentOffset + activeTabBounding.right - navScrollBounding.right;
|
||||
}
|
||||
|
||||
if(currentOffset !== newOffset){
|
||||
this.setOffset(Math.max(newOffset, 0));
|
||||
}
|
||||
},
|
||||
updateNavScroll(){
|
||||
const navWidth = this.$refs.nav.offsetWidth;
|
||||
const containerWidth = this.$refs.navScroll.offsetWidth;
|
||||
const currentOffset = this.getCurrentScrollOffset();
|
||||
if (containerWidth < navWidth) {
|
||||
this.scrollable = true;
|
||||
if (navWidth - currentOffset < containerWidth) {
|
||||
this.setOffset(navWidth - containerWidth);
|
||||
}
|
||||
} else {
|
||||
this.scrollable = false;
|
||||
if (currentOffset > 0) {
|
||||
this.setOffset(0);
|
||||
}
|
||||
}
|
||||
},
|
||||
handleResize(){
|
||||
this.updateNavScroll();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -232,10 +319,18 @@
|
|||
this.updateBar();
|
||||
this.updateStatus();
|
||||
this.broadcast('Table', 'on-visible-change', true);
|
||||
this.$nextTick(function(){
|
||||
this.scrollToActiveTab();
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.showSlot = this.$slots.extra !== undefined;
|
||||
this.observer = elementResizeDetectorMaker();
|
||||
this.observer.listenTo(this.$refs.navWrap, this.handleResize);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.observer.removeListener(this.$refs.navWrap, this.handleResize);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -56,6 +56,29 @@
|
|||
|
||||
&-nav-right{
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
&-nav-prev{
|
||||
position:absolute;
|
||||
line-height: 32px;
|
||||
cursor: pointer;
|
||||
left:0;
|
||||
}
|
||||
|
||||
&-nav-next{
|
||||
position:absolute;
|
||||
line-height: 32px;
|
||||
cursor: pointer;
|
||||
right:0;
|
||||
}
|
||||
|
||||
&-nav-scrollable{
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
&-nav-scroll-disabled{
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-nav {
|
||||
|
|
Loading…
Add table
Reference in a new issue