import findIndex from 'lodash/findIndex' import Panel from './panel.vue' import TabNav from './tabNav.jsx' // import Tab from './item' import DrpMenus from './drpMenus' const Tabs = { name: 'PTabs', props: { value: {} }, watch: { value(value) { // let id = 'tab_' + value; // let id =value; // this.$nextTick(r => { // debugger // let tabObj = this.$refs['TabNavs']; // if (tabObj.$refs[id] == null) return; // let scrollLeft = tabObj.$refs[id].$el.offsetLeft, // scrollArea = tabObj.$refs[id].$el.parentNode.parentNode; // if (scrollArea.offsetWidth < scrollLeft) { // scrollArea.scrollLeft = scrollLeft; // } else if (scrollArea.scrollLeft > scrollLeft) { // scrollArea.scrollLeft = scrollLeft; // } // }); this.setCurrentName(value) } }, 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); }, 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; } } else if (this.panels.length !== 0) { 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'] 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(); this.$refs['domTabBody'].style.height = this.$el.offsetHeight - this.$refs['domTabHead'].offsetHeight + 'px'; 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.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.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.scrollPressTimer = setInterval(function () { me.handleScrollRt(10); }, 10); }, handleScrollRtMouseUp() { clearInterval(this.scrollPressTimer); }, handleTabChange(name) { this.setCurrentName(name); }, handleTabClose(name) { this.closeItem(name); this.$refs['TabNavs'].$forceUpdate(); }, handleTabCloseAll(){ this.$emit('onRemoveAllTab'); this.$refs['TabNavs'].$forceUpdate(); this.resize(); }, handleTabCloseLt(name,index){ this.$emit('onRemoveLeft',name,index); this.$refs['TabNavs'].$forceUpdate(); this.resize(); }, handleTabCloseRt(name,index){ this.$emit('onRemoveRight',name,index); this.$refs['TabNavs'].$forceUpdate(); this.resize(); }, handleTabCloseOt(name,index){ this.$emit('onRemoveOther',name,index); this.$refs['TabNavs'].$forceUpdate(); this.resize(); }, handleFullScreen(){ this.$emit('onFullScreen') } }, render(h) { let children = this.panels; let navData={ props:{ panels:children }, on:{ onTabChange: this.handleTabChange, onTabClose: this.handleTabClose, onTabCloseAll: this.handleTabCloseAll, onTabCloseLt:this.handleTabCloseLt, onTabCloseRt:this.handleTabCloseRt, onTabCloseOt:this.handleTabCloseOt, 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, } }, scrollRtBtn = { style: { display: this.showScroll ? 'inline-block' : 'none' }, on: { //click:this.handleScrollRt, mousedown: this.handleScrollRtMouseDown, mouseup: this.handleScrollRtMouseUp, } }, moreBtn = { on: { mouseover: this.handleShowDrpMenus, mouseout: this.handleHideDrpMenus } }, drpMenus = { props: { children: children }, on: { click: this.handleMoreMenuClick, onTabChange: this.handleTabChange, onTabClose: this.handleTabClose } }, hideSty = { on: { mouseover: this.hideTab, mouseout: this.show, click: ()=>{alert(12313)} } }; return ( <div class="pl-tabs"> <div class="pl-tabs-hd" ref='domTabHead' {...hideSty}> <div class="pl-tabs-tool" ref='domTabTool'> <div class="item" title={$lang('scrollLeft')||'滚动左侧'} ref='domTabScrollLt' {...scrollLtBtn}> <i class="iconfont icon-arrow-left"></i> </div> <div class="item" title={$lang('scrollRight')||'滚动右侧'} ref='domTabScrollRt' {...scrollRtBtn}> <i class="iconfont icon-arrow-right"></i> </div> <div class="item" title={$lang('more')||'更多'} 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'> {this.$slots.default} </div> </div> ) } } export default Tabs;