• Vue项目中左右布局支持拉伸宽度


    <template>
      <el-row :gutter="10">
        <el-col
          :span="5"
          v-show="type === '2' && sidebar.opened"
          style="margin-top: 10px;"
        >
          <data-tree
            :treeLazy="treeLazy"
            :data="treeData"
            :currentKey="treeCurrentKey"
            @show-lazy-tree="showLazyTree"
            @tree-node-click="handleTreeNodeClick"
          >
          </data-tree>
    
          <lazy-tree
            :treeLazy="treeLazy"
            :currentKey="treeCurrentKey"
            @tree-node-click="handleTreeNodeClick"
            @lazy-data="lazyData"
          ></lazy-tree>
          <div
            class="pull-line"
            @mousedown="canDrag = true"
            @mouseup="resetStyle"
          ></div>
        </el-col>
    
        <el-col :span="type === '2' && sidebar.opened ? 19 : 24">
          <data-search
            v-if="searchData"
            :fields="searchFields"
            :formData="searchData"
            :columnModel="columnModel"
            @getRelatedOptions="getRelatedOptions"
            @search="search"
            @formStatus="getSearchFormStatus"
          >
            <template slot="search">
              <slot name="search"></slot>
            </template>
          </data-search>
    
          <data-tab v-if="modelTabs.length > 0" :modelTabs="modelTabs"></data-tab>
    
          <data-tree-table
            v-if="type === '1'"
            :data="data"
            :columns="tableColumns"
            :selectorType="selectorType"
            :showTableOperate="showTableOperate"
            :height="tHeight"
            :selectionWidth="selectionWidth"
            :currentRows="currentRows"
            @select="select"
            @selection-change="handleSelectionChange"
            :nonOptional="nonOptional"
            :lazy="tablelazy"
            :searchData="searchData"
          >
            <template slot="operate" slot-scope="scope">
              <slot name="tableOperate" v-bind="scope"></slot>
            </template>
            <template slot="operateMore" slot-scope="scope">
              <slot name="tableOperateMore" v-bind="scope"></slot>
            </template>
          </data-tree-table>
    
          <data-table
            v-if="type !== '1'"
            :data="data"
            :columns="tableColumns"
            @sort-change="handleSortChange"
            @selection-change="handleSelectionChange"
            @select="select"
            :selectorType="selectorType"
            :currentRows="currentRows"
            :showTableOperate="showTableOperate"
            :height="tHeight"
            :OperateWith="OperateWith"
          >
            <template slot="operate" slot-scope="scope">
              <slot name="tableOperate" v-bind="scope"></slot>
            </template>
            <template slot="operateMore" slot-scope="scope">
              <slot name="tableOperateMore" v-bind="scope"></slot>
            </template>
          </data-table>
    
          <div v-if="type !== '1' && pageInfo" class="pagination_bar">
            <fd-pagebar
              v-bind="$attrs"
              v-on="$listeners"
              :current-page.sync="pageInfo.pageNum"
              :page-size="pageInfo.pageSize"
              :page-sizes="pageSizes"
              layout="sizes, prev, pager, next, jumper"
              :total="pageInfo.total"
            >
            </fd-pagebar>
          </div>
        </el-col>
      </el-row>
    </template>
    
    <script>
    import dataTree from '../DataList/tree';
    import lazyTree from '../DataList/lazy-tree';
    import dataSearch from '../DataList/search';
    import dataTable from './table';
    import dataTreeTable from './tree-table';
    import { mapGetters } from 'vuex';
    
    export default {
      name: 'de-data-list',
      components: {
        dataSearch,
        dataTable,
        lazyTree,
        dataTreeTable,
        dataTree
      },
      props: {
        treeLazy: {
          type: Boolean,
          default: false
        },
        selectionWidth: {
          type: String,
          default: '48'
        },
        columnModel: {
          type: Object,
          default: () => {}
        },
        type: {
          type: String, // 0-普通列表 1-treeTable 2-tree 和 table
          default: '0'
        },
        treeData: {
          type: Array,
          default: () => []
        },
        treeCurrentKey: {
          type: String,
          default: () => ''
        },
        columns: {
          type: Array,
          default: () => []
        },
        searchData: {
          type: Object
        },
        data: {
          type: Array,
          default: () => []
        },
        pageInfo: {
          type: Object
        },
        selectorType: {
          type: String,
          default: () => ''
        },
        currentRows: {
          type: Array,
          default: () => []
        },
        height: [String, Number],
        nonOptional: String,
        tablelazy: Boolean,
        pageSizes: {
          type: Array,
          default: () => [10, 20, 30, 40]
        },
        modelTabs: {
          type: Array,
          default: () => []
        },
        OperateWith: {
          type: Number,
          default: 70
        }
      },
      data() {
        return {
          canDrag: false,
          baseColumnWidth: 100,
          searchFormStatus: false
        };
      },
      computed: {
        ...mapGetters({ sidebar: 'foundation/app/sidebar' }),
        searchFields() {
          let fields = this.columns.filter(item => {
            return item.searchableFlag === '1';
          });
          return fields;
        },
        tableColumns() {
          let columns = this.columns;
          columns.map(item => {
            item.widthFactor = item.widthFactor ? item.widthFactor : 1;
            item.width = item.widthFactor * this.baseColumnWidth;
          });
          return columns;
        },
        scopedSlots() {
          return this.$scopedSlots;
        },
        slots() {
          return this.$slots;
        },
        showTableOperate() {
          return !!this.scopedSlots.tableOperate;
        },
        searchFormHeight() {
          let height = null;
          let fieldsLength = this.searchFields.length;
          let rows = 0;
          if (fieldsLength > 0 && fieldsLength <= 3) {
            // 第一行
            rows = 1;
          } else if (fieldsLength > 3 && fieldsLength < 10) {
            // 从第二行开始算 + 1 = 总共几行
            rows = Math.ceil((fieldsLength - 3) / 3) + 1;
          } else {
            rows = 5; //searcharea的区域高度固定位200 每行40 所以是5行
          }
          // rows 是行数, 40 是行高
          height = rows * 40;
    
          if (this.searchFormStatus) {
            return height + 80; // 80 包含按钮区域及查询条件里面的padding值
          } else {
            return 60;
          }
        },
        tHeight() {
          if (this.height) {
            return this.height;
          }
          let height = null;
          let containerHeight = this.$store.state.foundation.app.containerHeight;
          let pageBar = this.type !== '1' ? 74 : 0;
          height = containerHeight - this.searchFormHeight - pageBar;
          return height + 'px';
        }
      },
      mounted() {
        // 右侧面板拉伸
        this.pl = document.querySelector('.pull-line');
        this.elCol5 = document.querySelector('.el-col-5');
        this.elCol19 = document.querySelector('.el-col-19');
        this.window = document.documentElement || document.body;
        this.leftTreeWidth = this.sidebar.opened ? 200 : 0;
        this.winWidth = this.window.clientWidth;
        this.padWidth = 50;
        this.window.addEventListener('mousemove', e => {
          if (this.canDrag) {
            let treeWidth = e.pageX - this.leftTreeWidth;
            if (e.pageX < this.leftTreeWidth) {
              this.elCol5.style.cursor = 'e-resize';
              this.pl.style.cursor = 'e-resize';
              this.window.style.cursor = 'e-resize';
              return;
            }
            if (e.pageX > this.winWidth - this.leftTreeWidth - 100) {
              this.elCol19.style.cursor = 'w-resize';
              this.pl.style.cursor = 'w-resize';
              this.window.style.cursor = 'w-resize';
              return;
            }
            this.elCol5.style.width = treeWidth + 'px';
            this.elCol19.style.width =
              this.winWidth - this.leftTreeWidth - treeWidth - this.padWidth + 'px';
            this.pl.style.cursor = 'col-resize';
            this.elCol5.style.cursor = 'col-resize';
            this.elCol19.style.cursor = 'col-resize';
          }
        });
        this.window.addEventListener('mouseup', () => {
          this.window.onmousemove = null;
          this.window.onmouseup = null;
        });
      },
      watch: {
        'sidebar.opened'() {
          if (!this.sidebar.opened) {
            this.$nextTick(() => {
              let e24 = document.querySelector('.el-col-24');
              e24 && (e24.style.width = '100%');
            });
          } else {
            this.$nextTick(() => {
              this.elCol19 &&
                (this.elCol19.style.width =
                  this.winWidth -
                  parseInt(getComputedStyle(this.elCol5).width) -
                  this.leftTreeWidth -
                  this.padWidth +
                  'px');
            });
          }
        }
      },
      methods: {
        resetStyle() {
          this.window.style.cursor = 'unset';
          this.elCol5.style.cursor = 'unset';
          this.elCol19.style.cursor = 'unset';
          this.canDrag = false;
        },
        lazyData(data, resolve) {
          this.$emit('lazy-data', data, resolve);
        },
        showLazyTree(data) {
          this.$emit('show-lazy-tree', data);
        },
        handleTreeNodeClick(data) {
          this.$emit('tree-node-click', data);
        },
        handleSortChange({ column, prop, order }) {
          this.$emit('sort-change', { column, prop, order });
        },
        handleSelectionChange(val) {
          this.$emit('selection-change', val);
        },
        getRelatedOptions(property) {
          this.$emit('getRelatedOptions', property);
        },
        search(data, type) {
          this.$emit('search', data, type);
        },
        select(row) {
          this.$emit('select', row);
        },
        getSearchFormStatus(status) {
          this.searchFormStatus = status;
        }
      }
    };
    /**
      *Attributes               说明                      可选值
    
        type                   页面展示类型               0(普通列表) 1(treeTable) 2(tree 和 table)
        selectorType           table 列类型              checkbox/radio(多选框/单选)
        currentRows            table 默认选中
        selectorType           查询区域默认数据
        treeData               tree 数据
    
      *methods                  方法说明                   参数说明
    
        handleTreeNodeClick     tree节点被点击时回调        data 该节点对象
        handleSortChange        表格排序                   { column, prop, order }
        handleSelectionChange   表格选择项变化时触发        selection
        search                  查询按钮被点击时触发        data 表单数据  type 查询类型( 0普通 1高级)
        handleSizeChange        pageSize改变时触发         每页条数
        handleCurrentChange     currentPage改变时触发      当前页
        select                  表格单选按钮被点击时回调     行数据
    */
    </script>
    <style lang="scss" scoped>
    // @import "../../../../styles/flex.scss";
    /deep/ .search-form {
      .el-form-item {
        height: 30px;
        .separator {
          font-style: normal;
          margin: 0 5px;
        }
      }
    }
    /deep/ .el-col-5 {
      position: relative;
    }
    .pull-line {
      position: absolute;
      right: 14px;
      top: 0;
       4px;
      height: 100%;
      cursor: col-resize;
    }
    .cursor-unset {
      cursor: unset;
    }
    </style>
    

      

    代码搬运工
  • 相关阅读:
    Android客户端与服务器交互方式-小结
    个人工作总结01
    第7周学习进度
    第6周学习进度
    PHP_D4_“简易聊天室 ”的具体技术实现
    php_D3_“简易聊天室 ”实现的关键技术 详解
    团队介绍
    最大联通子数组
    构建之法阅读笔记04
    大道至简阅读笔记04
  • 原文地址:https://www.cnblogs.com/tw6668/p/15629686.html
Copyright © 2020-2023  润新知