08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / project / hivuiMain / views / layout / components / tabpanel / tabs.jsx
caibinghong on 4 Jun 2021 add

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;