import findIndex from 'lodash/findIndex'
import Panel from './panel.vue'
import TabNav from './tabNav.jsx'
import DrpMenus from './drpMenus'
const Tabs = {
name: 'PTabs',
props: {
value: {},
hasMoreMenu:{
type:Boolean,
default:true
},
hasContextMenu:{
type:Boolean,
default:true
},
isSinglePage:{
type:Boolean,
default:false
},
},
watch: {
value(value) {
if(value==this.currentName){
return;
}
this.setCurrentName(value)
},
},
inject:['showTab','hideTab'],
data() {
return {
currentName: this.value || this.activeName,
contextMenuKey: null,
scrollStep: 115,
showScroll: false,
panels: []
}
},
created() {
this.$on('tab-nav-update', this.calcPaneInstances.bind(null, true));
},
mounted() {
this.calcPaneInstances();
window.addEventListener('resize',this.resize);
},
updated() {
this.calcPaneInstances();
},
beforeDestroy() {
window.removeEventListener('resize',this.resize);
},
methods: {
setCurrentName(value) {
this.currentName = value;
//绑定提是v-model所以这里要加一下,这样可以对 props 传进来的value 进行改变
this.$emit('input', value);
this.$nextTick(r=>{
let panel = this.getItem(value);
this.$emit('onActiveTab',panel);
});
},
calcPaneInstances() {
//收集插槽里头的组件实例,以重新渲染
if (this.$slots.default) {
const panelslots = this.$slots.default.filter(vnode => vnode.tag &&
vnode.componentOptions && vnode.componentOptions.Ctor.options.name === 'PTabpanel');
// update indeed
const panels = panelslots.map(({ componentInstance }) => componentInstance);
const panelsChanged = !(panels.length === this.panels.length && panels.every((pane, index) => pane === this.panels[index]));
if (panelsChanged) {
this.panels = panels;
this.$set(this,'panels',panels)
}
} else if (this.panels.length !== 0) {
this.$set(this,'panels',[])
}
},
closeItem(key) {
let me = this;
me.$emit('onRemoveTab', key);
me.resize();
},
closeCurItem() {
this.closeItem(this.currentName);
},
getItemIndex(name) {
let index = findIndex(this.panels, item => {
return item.name == name;
});
return index;
},
getItem(name) {
let index = findIndex(this.panels, item => {
return item.name == name;
});
if (index > -1) {
return this.panels[index];
}
return null;
},
getItemObj(name) {
let panel = this.getItem(name);
if (panel == null) return null;
return {
//.$refs['TabNavs']
id:name,
uid:name,
name:name,
tabEl: this.$el.querySelector('#tab_'+name),//null
tabPanelEl: panel.$el,
tabPanelIframeEl: panel.$el.querySelector('iframe')
};
},
getSeldItemObj() {
return this.getItemObj(this.currentName);
},
resize() {
this.$refs['TabNavs'].resize();
// console.log('height', this.$refs['domTabHead'].offsetHeight)
// console.log('offsetHeight', this.$el.offsetHeight)
//this.$refs['domTabHead'].style.display=this.isSinglePage ? "none" : "block";
this.$refs['domTabBody'].style.height = this.$el.offsetHeight - this.$refs['domTabHead'].offsetHeight + 'px';
// console.log('main height', this.$refs['domTabBody'].style.height)
let tabScroll = this.$refs['domTabScroll'];
this.showScroll = tabScroll.offsetWidth < tabScroll.scrollWidth;
},
handleShowDrpMenus(evt) {
evt.stopPropagation();
const rects = evt.currentTarget.getClientRects()[0];
this.$refs['cmp-drpMenus'].show(rects.left,rects.top + rects.height);
},
handleHideDrpMenus() {
this.$refs['cmp-drpMenus'].hide();
},
handleMoreMenuClick(vm, event) {
// this.activeKey = vm.$el.getAttribute('alt');
this.resize();
},
handleScrollLt(step) {
let el = this.$refs['domTabScroll'];
el.scrollLeft = el.scrollLeft - (step || this.scrollStep);
},
handleScrollLtMouseDown() {
let me = this;
me.handleScrollLtMouseUp();
me.scrollPressTimer = setInterval(function () {
me.handleScrollLt(10);
}, 10);
},
handleScrollLtMouseUp() {
clearInterval(this.scrollPressTimer);
},
handleScrollRt(step) {
let el = this.$refs['domTabScroll'];
el.scrollLeft = el.scrollLeft + (step || this.scrollStep);
},
handleScrollRtMouseDown() {
let me = this;
me.handleScrollRtMouseUp();
me.scrollPressTimer = setInterval(function () {
me.handleScrollRt(10);
}, 10);
},
handleScrollRtMouseUp() {
clearInterval(this.scrollPressTimer);
},
handleTabChange(panel) {
if(panel.name==this.currentName){
return;
}
this.setCurrentName(panel.name);
},
handleTabClose(name) {
this.closeItem(name);
},
handleTabCloseAll(){
this.$emit('onRemoveAllTab');
this.resize();
},
handleTabCloseLt(name,index){
this.$emit('onRemoveLeft',name,index);
this.resize();
},
handleTabCloseRt(name,index){
this.$emit('onRemoveRight',name,index);
this.resize();
},
handleTabCloseOt(name,index){
this.$emit('onRemoveOther',name,index);
this.resize();
},
handleFullScreen(){
this.$emit('onFullScreen')
}
},
render(h) {
let {hasMoreMenu,hasContextMenu}=this;
let children = this.panels;
let headStyle={
style:{
display: this.isSinglePage ? "none" : "block"
}
}
let navData={
props:{
panels:children,
hasContextMenu:hasContextMenu
},
on:{
onTabChange: this.handleTabChange,
onTabClose: this.handleTabClose,
onTabCloseAll: this.handleTabCloseAll,
onTabCloseLt:this.handleTabCloseLt,
onTabCloseRt:this.handleTabCloseRt,
onTabCloseOt:this.handleTabCloseOt,
onFullScreen:this.handleFullScreen
},
ref:'domTabSrcollInner'
};
let scrollLtBtn = {
style: {
display: this.showScroll ? 'inline-block' : 'none'
},
on: {
//click:this.handleScrollLt,
mousedown: this.handleScrollLtMouseDown,
mouseup: this.handleScrollLtMouseUp,
mouseleave:this.handleScrollLtMouseUp,
},
title:this.$t('hivuiMain_tab_scroll_lt')
}, scrollRtBtn = {
style: {
display: this.showScroll ? 'inline-block' : 'none'
},
on: {
//click:this.handleScrollRt,
mousedown: this.handleScrollRtMouseDown,
mouseup: this.handleScrollRtMouseUp,
mouseleave:this.handleScrollRtMouseUp,
},
title:this.$t('hivuiMain_tab_scroll_rt')
}, moreBtn = {
on: {
mouseover: this.handleShowDrpMenus,
mouseout: this.handleHideDrpMenus
},
title:this.$t('hivuiMain_tab_scroll_more')
}, drpMenus = {
props: {
children: children
},
on: {
click: this.handleMoreMenuClick,
onTabChange: this.handleTabChange,
onTabClose: this.handleTabClose
}
}, hideSty = {
on: {
mouseout: this.showTab,
mouseover: this.hideTab
}
};
return (
<div class="pl-tabs">
<div class="pl-tabs-hd" ref='domTabHead' {...headStyle}>
<div class="pl-tabs-tool" ref='domTabTool'>
<div class="item" ref='domTabScrollLt' {...scrollLtBtn}>
<i class="iconfont icon-arrow-left"></i>
</div>
<div class="item" ref='domTabScrollRt' {...scrollRtBtn}>
<i class="iconfont icon-arrow-right"></i>
</div>
{
hasMoreMenu&&(
<div class="item" ref='domTabScrollMore' {...moreBtn} >
<i class="iconfont icon-arrow-down"></i>
<DrpMenus ref="cmp-drpMenus" {...drpMenus}></DrpMenus>
</div>
)
}
</div>
<div class="pl-tabs-scroll" ref='domTabScroll'>
<TabNav {...navData} ref='TabNavs'></TabNav>
</div>
</div>
<div class="pl-tabpanel-bd" ref='domTabBody' {...hideSty}>
{this.$slots.default}
</div>
</div>
)
}
}
export default Tabs;