vue实现elementui的table和datepicker的操作

组件对象说明

      一个组件分别有自己的 属性 Attributes    事件Events    方法Methods

      调用属性和调用事件的形式是不一样的  属性是用  :props     事件是用 @event   所以在使用之前一定要弄清楚给组件添加的是属性还是添加事件

    <!-- 表格组件 -->
    <el-table :data="data"
              :height="height"
              :span-method="spanMethod"
              ref="table"
              @selection-change="handleSelectionChange"
              @sort-change="handleSortChange"
              v-loading="loading">

:span-method 表示接收属性
spanMethod是从子表格组件中传递过来的属性名称
@selection-change 表示接收事件

<script>
  export default {
    data() {
      return {
        // 表格高度
        tableHeight: 0
      }
    },
    props: {
      // 表格数据
      data: {
        type: Array,
        default() {
          return [];
        }
      },
      // 表格列配置
      columnConfig: {
        type: Array,
        default() {
          return [];
        }
      },
      // 表格高度
      height: {
        type: [String, Number],
        default() {
          return 400;
        }
      },
      //表格是否显示折叠信息
      expand: {
        type: Boolean,
        default() {
          return false;
        }
      },
      // 分页参数-当前页
      pageIndex: {
        type: Number,
        default() {
          return 1;
        }
      },
      // 分页参数-每页条数
      pageSize: {
        type: Number,
        default() {
          return 10;
        }
      },
      // 分页参数-每页条数候选项
      pageSizes: {
        type: Array,
        default() {
          return [10, 20, 50, 100];
        }
      },
      // 分页参数-总条数
      total: {
        type: Number,
        default() {
          return 0;
        }
      },
      // 是否显示loading
      loading: {
        type: Boolean,
        default() {
          return false;
        }
      },
      spanMethod:{
        type:Function,
        default(){
          return()=>{};
        }
      }
    },
    methods: {
      /**
       * 处理行选中状态变化
       * @param data
       */
      handleSelectionChange(data) {
        this.$emit('selection-change', data);
      },
      /**
       * 处理排序条件变化
       * @param data
       */
      handleSortChange(data) {
        this.$emit('sort-change', data);
      }
}
基类表格配置
      <div style="margin-top:10px">
        <bee-table :data="interfaceList" 
                  border
                 :spanMethod="objectSpanMethod"
                 :pageIndex="currentPage"
                 :pageSize="pageSize"
                 :column-config="Ins2_TABLE_COLUMN"
               @size-change="handleSizeChange"
               @current-change="handleCurrentChange"
               :total="total"
               v-loading="tbflag">
        </bee-table>

data(){
      return {
        startTtime:"",
        endTime:"",
        pickerOptions:utils.setTimeOPtions(),
        value2:'',
        value:'',
        total: 0,         //总记录数
        currentPage:1,   //初始页
        pageSize:10,    // 每页的数据
        tbflag:false,
        Ins2_TABLE_COLUMN,
        interfaceList:[],
        spanMethod:""
      };
    }

    methods:{
      objectSpanMethod({ row, column, rowIndex, columnIndex })
      {
         if (columnIndex === 0) {
            console.log("eeeeee");
          if (rowIndex % 2 === 0) {
            return {
              rowspan: 2,
              colspan: 1
            };
          } else {
            return {
              rowspan: 0,
              colspan: 0
            };
          }
        }
      }
子类表格组件

 

具体效果

 

注意es6对属性类型的强制性检查 如果声明属性的类型和返回的类型不匹配 会造成一些异常

    props: {
      // 表格数据
      data: {
        type: Array,
        default() {
          return [];
        }
      },
      // 表格列配置
      columnConfig: {
        type: Array,
        default() {
          return [];
        }
      },
      // 表格高度
      height: {
        type: [String, Number],
        default() {
          return 400;
        }
      },
      //表格是否显示折叠信息
      expand: {
        type: Boolean,
        default() {
          return false;
        }
      },
      // 分页参数-当前页
      pageIndex: {
        type: Number,
        default() {
          return 1;
        }
      },
      // 分页参数-每页条数
      pageSize: {
        type: Number,
        default() {
          return 10;
        }
      },
      // 分页参数-每页条数候选项
      pageSizes: {
        type: Array,
        default() {
          return [10, 20, 50, 100];
        }
      },
      // 分页参数-总条数
      total: {
        type: Number,
        default() {
          return 0;
        }
      },
      // 是否显示loading
      loading: {
        type: Boolean,
        default() {
          return false;
        }
      },
      spanMethod: {
        type: [Function],
        default() {
          //函数类型的属性就一定要返回一个函数
          return ()=>{};
        }
      }
    }
组件包含的属性声明

 

示例效果代码

        <bee-table :data="interfaceList" 
                 :spanMethod="objectSpanMethod"
                 :border=true
                 :pageIndex="currentPage"
                 :pageSize="pageSize"
                 :column-config="Ins2_TABLE_COLUMN"
               @size-change="handleSizeChange"
               @current-change="handleCurrentChange"
               :total="total"
               v-loading="tbflag">
        </bee-table>



    methods:{
      objectSpanMethod({ row, column, rowIndex, columnIndex }){
          const span = column['property'] + '-span'
          if(row[span]){
             return row[span]
          }
      },
      mergeTableRow(data, merge) {
        if (!merge || merge.length === 0) {
          return data
        }
        merge.forEach((m) => {
          const mList = {}
          data = data.map((v, index) => {
            const rowVal = v[m]
            if (mList[rowVal]) {
              mList[rowVal]++
              data[index - (mList[rowVal] - 1)][m + '-span'].rowspan++
              v[m + '-span'] = {
                rowspan: 0,
                colspan: 0
              }
            } else {
              mList[rowVal] = 1
              v[m + '-span'] = {
                rowspan: 1,
                colspan: 1
              }
            }
             return v
             })
          })
        return data
      },
     getinferfaceCall()
     {
      this.tbflag=true;
      return this.$http.getInterfaceCall(
          {
            "pageIndex":this.currentPage,
            "pageSize":this.pageSize,
            "startTime":this.startTtime,
            "endTime":this.endTime
           },{notify:true})
         .then((data) => 
          {
            this.interfaceList=data.list;
            this.total=data.total;
          }).finally(() =>{
            this.tbflag=false;
            this.interfaceList = this.mergeTableRow(this.interfaceList, ['businessname', 'appname']);
          });
     }
   }
子表格
    <el-table :data="data"
              :height="height"
              :span-method="spanMethod"
              :border="border"
              ref="table"
              @selection-change="handleSelectionChange"
              @sort-change="handleSortChange"
              v-loading="loading">

 props: {
      spanMethod: {
        type: [Function],
        default() {
          return ()=>{};
        }
      },
       border: {
        type: Boolean,
        default() {
          return false;
        }
      }
    }
父表格

 

vue实现表格不同的分页样式功能

    <!-- 分页组件 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageIndex"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      :layout="paginationlayout"
      :total="total"/>

<script>
  export default {
    data() {
      return {
        // 表格高度
        tableHeight: 0
      }
    },
    props: {
      // 表格数据
      data: {
        type: Array,
        default() {
          return [];
        }
      },
     //设置分页样式的默认值
      paginationlayout:{
        type: [String, Number],
        default() {
          return "total, sizes, prev, pager, next, jumper";
        }
      }
    }
父组件定义
    <bee-table :data="tbList"
               :column-config="LOG_TABLE_COLUMN"
               :pageIndex="currentPage"
               :pageSize="pageSize"
               v-loading="tbflag"
               //指定自己的分页样式 不使用默认样式
               :paginationlayout="pglayout"
               @size-change="handleSizeChange"
               @current-change="handleCurrentChange"
               :total="total">
    </bee-table>



    data()
    {
      return {
        total: 0,         //总记录数
        currentPage:1,   //初始页
        pageSize:10,    // 每页的数据
        pickerOptions:utils.setTimeOPtions(),
        value1: [new Date(2010, 10, 10, 10, 10), new Date(2010, 10, 11, 10, 10)],
        value2: '',
        highinput:"",
        startTime:"",
        endTime:"",
        tbList:[],
        tbflag:false,
        LOG_TABLE_COLUMN,
        dHeight:"200px",
        svalue:true,
        pickerOptions:utils.setTimeOPtions(),
        pglayout:"total, sizes, prev, next, jumper"
      }
    }
子组件

 

Elementui日期控制选择范围

     <el-date-picker
      v-model="value2"
      type="datetimerange"
      :picker-options="pickerOptions"
      range-separator="至"
      start-placeholder="开始日期"
      end-placeholder="结束日期"
      align="right">
    </el-date-picker>




this.value2 = this.setDefaultTime();
this.startTime=this.value2[0];
this.endTime=this.value2[1];


    data()
    {
      return {
        total: 0,         //总记录数
        currentPage:1,   //初始页
        pageSize:10,    // 每页的数据
        pickerOptions:utils.setTimeOPtions(),
        value2: '',
        highinput:"*",
        startTime:"",
        endTime:"",
        tbList:[],
        tbflag:false,
        LOG_TABLE_COLUMN,
        dHeight:"200px",
        svalue:true,
        pglayout:"total,sizes,prev,next"
      }


    methods: {
      setDefaultTime() {
       const end = new Date();
       const start = new Date();
       start.setTime(start.getTime() - 3600 * 250);
       return [start,end];
     }
页面
  setTimeOPtions()
  {
    let _minTime=null;
    let _maxTime=null;
    return {
           onPick(time){
            // 如果选择了只选择了一个时间
            if (!time.maxDate) {
              let curTime = (new Date()).getTime();
              let timeRange = 6*24*60*60*1000;  // 6天
              _minTime = time.minDate.getTime() - timeRange; // 最小时间
              _maxTime = time.minDate.getTime() + timeRange; // 最大时间
              if (_maxTime > curTime){
                 _maxTime = curTime;
              }
              // 如果选了两个时间,那就清空本次范围判断数据,以备重选
            } else {
              _minTime = _maxTime = null
            }
           },
           disabledDate(time) {
            // onPick后触发
            let curTime = (new Date()).getTime();
            if(_minTime && _maxTime){
              return time.getTime() < _minTime || time.getTime() > _maxTime
            }
            else
            {
              //不能选择大于今天的日期
              return time.getTime()>curTime;
            }
           },
           shortcuts: [
           {
            text: '最近15分钟',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 250);
              picker.$emit('pick', [start, end]);
             }
           },
           {
            text: '最近30分钟',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 500);
              picker.$emit('pick', [start, end]);
            }
           }, {
            text: '最近1小时',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000);
              picker.$emit('pick', [start, end]);
            }
           }, {
            text: '最近12小时',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 *12);
              picker.$emit('pick', [start, end]);
            }
          }]
        };
  }
js组件

 

 

 

elementUI实现表格和合并

    实现效果

         按照业务类型和应用名称进行去重合并单元格

         这个功能对后台返回的数据列表格式是有要求的 必须按照需要被分组的列进行排序(可以是升序也可以是降序) 

         属于同一个业务类型或者应用名称的记录必须排列在一起

 

   如果返回的数据不是有序的  那么页面的显示会如下

 

 

 后台返回的数据列表businessname的值是由暂无业务代码和业务代码1随机排列的 导致页面表格按照业务代码合并行列时出现异常

 

 

 

解决办法 在后台查询好数据后按照业务代码先进行排序 然后再返回给前端

        userChoiceTime_start = self.formartStartTime(startTime)
        userChoiceTime_end = self.formartEndTime(endTime)
        index_list_pattern=self.getindexes(startTime,endTime)
        pageIndex = int(pageIndex)
        pageSize = int(pageSize)
        if sortColumn=="":
            sortColumn = "businessname"



        reverse=False
        floatflag=False
        if sortType == "desc":
            reverse=True
        if sortColumn in ["avgtime","requestCount","errRequest","maxtime","mintime"]:
            floatflag=True
        if floatflag:
            ilist = sorted(ilist,key=lambda e:float(e.__getitem__(sortColumn)),reverse=reverse)
        else:
            ilist = sorted(ilist, key=lambda e:e.__getitem__(sortColumn), reverse=reverse)



        if querytype != "excel":
            reslist=ilist[(pageIndex-1)*pageSize:pageIndex*pageSize]
            data = {'code': 'SUCCESS', 'message': '', 'data': {"total":len(ilist),"list":reslist}}
            return data
        else:
            data = {'code': 'SUCCESS', 'message': '', 'data': {"total": len(ilist), "list": ilist}}
            return data
后台查询
[{'appname': 'wszx-web', 'avgtime': '36.75', 'errRequest': 0, 'maxtime': '53.00', 'interface': '111111', 'mintime': '23.00', 'requestCount': 4, 'businessname': '业务代码1'}, {'appname': 'wszx-web', 'avgtime': '21.00', 'errRequest': 0, 'maxtime': '22.00', 'interface': '111111', 'mintime': '20.00', 'requestCount': 2, 'businessname': '业务代码1'}, {'appname': 'wszx-web', 'avgtime': '1517.00', 'errRequest': 0, 'maxtime': '2110.00', 'interface': '111111', 'mintime': '924.00', 'requestCount': 2, 'businessname': '业务代码1'}, {'appname': 'wszx-web', 'avgtime': '68.00', 'errRequest': 0, 'maxtime': '113.00', 'interface': '1111111', 'mintime': '23.00', 'requestCount': 2, 'businessname': '业务代码1'}, {'appname': 'wszx-web', 'avgtime': '119.50', 'errRequest': 0, 'maxtime': '165.00', 'interface': '11111', 'mintime': '74.00', 'requestCount': 2, 'businessname': '业务代码1'}, {'appname': 'wszx-web', 'avgtime': '21.00', 'errRequest': 0, 'maxtime': '21.00', 'interface': '111111', 'mintime': '21.00', 'requestCount': 1, 'businessname': '业务代码1'}, {'appname': 'wszx-web', 'avgtime': '111.00', 'errRequest': 0, 'maxtime': '111.00', 'interface': '11111111', 'mintime': '111.00', 'requestCount': 1, 'businessname': '业务代码1'}, {'appname': 'hgzx-web', 'avgtime': '84.75', 'errRequest': 0, 'maxtime': '370.00', 'interface': '1111111', 'mintime': '32.00', 'requestCount': 8, 'businessname': '业务代码2'}, {'appname': 'hgzx-web', 'avgtime': '3173.17', 'errRequest': 0, 'maxtime': '6480.00', 'interface': '111111', 'mintime': '102.00', 'requestCount': 6, 'businessname': '业务代码2'}, {'appname': 'hgzx-web', 'avgtime': '63.50', 'errRequest': 0, 'maxtime': '87.00', 'interface': '11111111', 'mintime': '40.00', 'requestCount': 2, 'businessname': '业务代码2'}, {'appname': 'hgzx-web', 'avgtime': '183.00', 'errRequest': 0, 'maxtime': '183.00', 'interface': '111111111', 'mintime': '183.00', 'requestCount': 1, 'businessname': '业务代码2'}]
按照指定列排序
<template>
  <div class="topology-container">
    <bee-breadcrumb/>
    <div id="applicationdiv" style="margin-left:30px">
      <el-date-picker
       v-model="value2"
       type="datetimerange"
       :picker-options="pickerOptions"
       range-separator=""
       start-placeholder="开始日期"
       end-placeholder="结束日期"
       align="right">
       </el-date-picker>
       &nbsp;&nbsp;
    <el-button type="primary" @click="handleQuery">查询</el-button>
      <div style="margin-top:10px">
        <bee-table :data="interfaceList" 
                 :spanMethod="objectSpanMethod"
                 :border=true
                 :pageIndex="currentPage"
                 :pageSize="pageSize"
                 :column-config="Ins2_TABLE_COLUMN"
               @size-change="handleSizeChange"
               @current-change="handleCurrentChange"
               :total="total"
               v-loading="tbflag">
        </bee-table>
      </div>
    </div>
  </div>
</template>
<script>
  import BeeBreadcrumb from '@/common/component/BeeBreadcrumb'
  import utils from '@/common/utils'
  import BeeTable from '@/common/component/BeeTable'
  import { Ins2_TABLE_COLUMN } from './constants'

  export default {
    components: {
      BeeBreadcrumb,
      BeeTable
    },
     data(){
      return {
        startTtime:"",
        endTime:"",
        pickerOptions:utils.setTimeOPtions(),
        value2:'',
        value:'',
        total: 0,         //总记录数
        currentPage:1,   //初始页
        pageSize:10,    // 每页的数据
        tbflag:false,
        Ins2_TABLE_COLUMN,
        interfaceList:[],
        spanMethod:"",
        needMergeArr: ['businessname', 'appname'],
        rowMergeArrs: {},
      };
    },
    mounted() {
      this.breadcrumbList = [
        {
          path: '',
          text: '分类统计详情'
        }
      ];
       this.value2 = this.setDefaultTime(); 
       this.startTtime=this.value2[0];
       this.endTime=this.value2[1];
       this.getinferfaceCall();
    },
    methods:{
      objectSpanMethod({ row, column, rowIndex, columnIndex }){
          const span = column['property'] + '-span'
          if(row[span]){
             return row[span]
          }
      },
      mergeTableRow(data, merge) {
        if (!merge || merge.length === 0) {
          return data
        }
        merge.forEach((m) => {
          const mList = {}
          data = data.map((v, index) => {
            const rowVal = v[m]
            if (mList[rowVal]) {
              mList[rowVal]++
              data[index - (mList[rowVal] - 1)][m + '-span'].rowspan++
              v[m + '-span'] = {
                rowspan: 0,
                colspan: 0
              }
            } else {
              mList[rowVal] = 1
              v[m + '-span'] = {
                rowspan: 1,
                colspan: 1
              }
            }
             return v
             })
          })
        return data
      },
      handleQuery()
      {
        this.startTtime=this.value2[0];
        this.endTime=this.value2[1];
        if(!this.startTtime || !this.endTime) {
           this.$message({
              showClose: true,
              message: '查询日期不能为空!',
              type: 'warning'
           });
           return;
        }
         this.getinferfaceCall();
      },
      setDefaultTime() {
       const end = new Date();
       const start = new Date();
       start.setTime(start.getTime() - 3600 * 250);
       return [start,end];
     },
     handleCurrentChange(pageIndex) 
     { 
        this.currentPage=pageIndex;
        this.getinferfaceCall();
     },
     handleSizeChange(pageSize) {
        this.currentPage = 1;
        this.pageSize= pageSize;
        this.getinferfaceCall();
     },
     getinferfaceCall()
     {
      this.tbflag=true;
      return this.$http.getInterfaceCall(
          {
            "pageIndex":this.currentPage,
            "pageSize":this.pageSize,
            "startTime":this.startTtime,
            "endTime":this.endTime
           },{notify:true})
         .then((data) => 
          {
            this.interfaceList=data.list;
            this.total=data.total;
          }).finally(() =>{
            this.tbflag=false;
            this.interfaceList = this.mergeTableRow(this.interfaceList, ['businessname', 'appname']);
          });
     }
   }
  }
</script>
<style lang="scss" scoped>
  .chart_example{
    margin-left:5px;
    width: 49%;
    height: 300px;
    border: 1px solid #C0C4CC;
    float:left;
  }
  .chart_example2{
    margin-left:5px;
    width: 330px;
    height: 270px;
    border: 1px solid #C0C4CC;
    float:left;
  }
  .chart_left
  {
     float:left;
     width:33%;
     height:100%;
     background-color:#f4f6f9;
     margin-left:3px;
  }
  .chart_right
   {
     margin-left:10px;
     float:left;
     width:65%;
   }
</style>
页面表格合并行

 

posted @ 2019-09-20 15:37  不懂123  阅读(2438)  评论(0)    收藏  举报