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

摘要:
˂data-tree:treeLazy="treeLazy":data="treeData":currentKey="treeCurrentKey"@show-lazy-tree="showLazyTree"@tree-node-cli
<template>
  <el-row :gutter="10">
    <el-col
      :span="5"
      v-show="type === '2' && sidebar.opened"
       
    >
      <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
         
        @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"
        : 
        :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"
        : 
        :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>

免责声明:文章转载自《Vue项目中左右布局支持拉伸宽度》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇源码分析Kafka 消息拉取流程SSL相关漏洞解决方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

封装Vue可选择列导出表格组件

1、创建ExportExcel.vue组件 <template> <div class="export_tools"> <div v-show="false"> <el-table id="out-table" style=" 100%;" :data="exportTable"> <...

链表的基础操作1

1.链表的重要操作 我们知道,链表的基础单位是一个个节点,那么第一步便是创建节点。 struct node{ typename data; //typename data 这里是数据域 node* next ; //指针域 }; 有一点要注意的是在C++中,是可以直接使用node的,而在C语言中,则需要使用struct node 不然会显示...

vue 图片下载到本地,图片保存到本地

  必须同源(访问的网站域名与服务器域名一致)才能下载 1 2 3 4 5 6 downs() {   var alink = document.createElement("a");   alink.href = this.shop.shoppic_url;   alink.download = "pic"; //图片名   al...

SpringBoot+Mybatis---这一篇就够了!

typora-copy-images-to: SpringBoot+Mybatisimages SpringBoot整合MyBatis ------ 既然你都开始整合Mybatis了,我相信基本的SpringBoot项目创建你自己肯定是可以搞定的,所以我在这里就不多赘述了,话不多B,让我们直奔主题 MyBatis---半自动ORM框架 现如今,常见的持久...

VueJS/Vuex/vue-router笔记- 开发/Error错误处理及优化相关记录

 开发记录备查笔记.....  Q.Vuejs(2.6.x):TS下使用Vuex例子:   记一个ts下的vuex store,备查   可以用以前的ES写法,但是想用强类型约束的话,就得改成TS的写法.   (吐槽:vue虽然已经全部用TS重构了,但还是有大量的any变量,希望随着以后的迭代,能完善成更出色的泛型类吧,现在的vuex真是不太好用,还不如自...

Comet 反Ajax: jQuery与PHP实现Ajax长轮询

原文地址(http://justcode.ikeepstudying.com/2016/08/comet-%E5%8F%8Dajax-%E5%9F%BA%E4%BA%8Ejquery%E4%B8%8Ephp%E5%AE%9E%E7%8E%B0ajax%E9%95%BF%E8%BD%AE%E8%AF%A2longpoll/) 页面代码: <!DOCTY...