exp-control-layout.tsx 4.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import './exp-control-layout.less';

/**
 * 导航部件布局组件
 *
 * @export
 * @class ExpControlLayout
 * @extends {Vue}
 */
@Component({})
export class ExpControlLayout extends Vue {

    /**
     * 是否挂载完毕
     *
     * @protected
     * @type {boolean}
     * @memberof ExpControlLayout
     */
    protected showAnimation: boolean = false;

    /**
     * 默认分割比例
     *
     * @type {number}
     * @memberof ExpControlLayout
     */
    public defaultSplit: number = 0.6;

    /**
     * 默认分割比例
     *
     * @type {number}
     * @memberof ExpControlLayout
     */
    public split: number = 1;

    /**
     * 旧分割比例
     *
     * @type {number}
     * @memberof ExpControlLayout
     */
    public oldSplit: number = this.defaultSplit;

    /**
     * 视图是否显示
     *
     * @type {boolean}
     * @memberof ExpControlLayout
     */
    public showView: boolean = false;

    /**
     * 视图显示变更
     *
     * @param {boolean} val
     * @param {boolean} oldVal
     * @memberof ExpControlLayout
     */
    @Watch('showView')
    public showViewWatch(val: boolean, oldVal: boolean): void {
        this.showAnimation = true;
        setTimeout(() => this.showAnimation = false, 500);
        if (val) {
            const s = this.split;
            this.split = this.oldSplit;
            this.oldSplit = s;
        } else {
            this.split = 1;
        }
    }

    /**
     * 选中视图数据
     *
     * @type {*}
     * @memberof ExpControlLayout
     */
    @Prop()
    public selectView: any;

    /**
     * 监控选中视图变更
     *
     * @param {*} val
     * @param {*} oldVal
     * @memberof ExpControlLayout
     */
    @Watch('selectView')
    public selectViewWatch(val: any, oldVal: any): void {
        if (val) {
            this.showView = true;
        } else {
            this.showView = false;
        }
    }

    /**
     * 展示模式
     *
     * @type {string}
     * @memberof ExpControlLayout
     */
    @Prop({ default: 'horizontal' })
    public mode!: 'horizontal' | 'vertical';

    /**
     * 部件宽度
     *
     * @type {number}
     * @memberof ExpControlLayout
     */
    @Prop({ default: 0 })
    public ctrlWidth!: number;

    /**
     * 部件高度
     *
     * @type {number}
     * @memberof ExpControlLayout
     */
    @Prop({ default: 0 })
    public ctrlHeight!: number;

    /**
     * 组件挂载完毕
     *
     * @memberof ExpControlLayout
     */
    public mounted(): void {
        const el: any = this.$el;
        if (this.ctrlWidth > 0 && this.mode === 'horizontal') {
            this.defaultSplit = 1 - parseFloat(((el.offsetWidth - this.ctrlWidth) / el.offsetWidth).toFixed(2));
        } else if (this.ctrlHeight > 0 && this.mode === 'vertical') {
            this.defaultSplit = 1 - parseFloat(((el.offsetHeight - this.ctrlHeight) / el.offsetHeight).toFixed(2));
        }
        if (this.showView) {
            this.split = this.defaultSplit;
        } else {
            this.oldSplit = this.defaultSplit;
        }
    }

    /**
     * 绘制可拖拽分隔
     *
     * @protected
     * @returns {*}
     * @memberof ExpControlLayout
     */
    protected renderSplit(): any {
        let showHeader = false;
        if (this.$slots.title || this.$slots.toolbar || this.$slots.quickSearch) {
            showHeader = true;
        }
        return <split class={{ 'exp-control-layout': true, 'animation': this.showAnimation }} v-model={this.split} mode={this.mode} min={(this.ctrlHeight > 0 || this.ctrlWidth > 0) ? this.defaultSplit : null}>
            <template slot={this.mode === 'horizontal' ? 'left' : 'top'}>
                <div class="exp-control-layout-exp">
                    {showHeader ? <div class="exp-header">
                        {this.$slots.title ? <div class="exp-header-title">
                            {this.$slots.title}
                        </div> : null}
                        {this.$slots.toolbar ? <div class="exp-toolbar">
                            {this.$slots.toolbar}
                        </div> : null}
                        {this.$slots.quickSearch ? <div class="exp-quick-search">
                            {this.$slots.quickSearch}
                        </div> : null}
                    </div> : null}
                    <div class={{ 'exp-content': true, 'hidden-header': !showHeader }}>
                        {this.$slots.expContent}
                    </div>
                </div>
            </template>
            <template slot={this.mode === 'horizontal' ? 'right' : 'bottom'}>
                <div class="exp-control-layout-view">
                    {this.$slots.default}
                </div>
            </template>
        </split>;
    }

    /**
     * 绘制内容
     *
     * @returns {*}
     * @memberof ExpControlLayout
     */
    public render(): any {
        return this.renderSplit();
    }
}