关于前端:elementui-table组件化重新封装

36次阅读

共计 12841 个字符,预计需要花费 33 分钟才能阅读完成。

1、话不多说先看成果

次要实现性能:筛选:输入框、下拉框、工夫;表格实用:多选、序号、排序、自定义、开关、链接可跳转、输入框、图片、自定义操作按钮(局部页面须要每行显示按钮不必所以大家按需增加)、惯例操作按钮(每行操作按钮都雷同无其余需要)、设置行背景色、分页

2、本文局部原创,大框架是复制的 https://blog.csdn.net/qq_37346639/article/details/115556605 这个博客,因为懒的本人写😂,依照需要改为本人所须要格局

3、筛选组件代码

<template>
    <div>
      <ul class="row-list" v-if="screenConfig.searchShow">
        <li v-for="(item,index) in screenConfig.formItem" :key="index">
          <label v-if="item.type !='operationBtn'">{{item.label}}:</label>
<!--          输入框 -->
          <el-input v-if="item.type ==='input'"clearable v-model.trim="screenConfig.searchParams[item.prop]"class="w215"size="small":placeholder="item.placeholder"></el-input>
<!--          下拉框 -->
          <el-select v-if="item.type ==='select'"filterable clearable v-model.trim="screenConfig.searchParams[item.prop]":placeholder="item.placeholder"size="small":multiple="item.multiple":filterable="item.filterable">
            <el-option v-for="selectItem in item.options" :key="selectItem[item.value]" :value="selectItem[item.value]"
                       :label="selectItem[item.leftLabel]" :disabled="selectItem.disabled">
              <span style="float: left">{{selectItem[item.leftLabel] }}</span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{selectItem[item.rightLabel] }}</span>
            </el-option>
          </el-select>
<!--          工夫选择器 -->
          <el-date-picker v-if="item.type ==='datePicker'"clearable v-model="screenConfig.searchParams[item.prop]":type="item.dateType"size="small":value-format="item.format"placeholder=" 请抉择 "range-separator=" 至 "start-placeholder=" 开始日期 "end-placeholder=" 完结日期 ">
          </el-date-picker>
<!--          自定义 -->
          <slot v-if="item.type =='custom'"name='customFilter'></slot>
          <!--          按钮 -->
          <span v-if="item.type =='operationBtn'"v-for="(operations, index) in item.operation":key="index">
                        <el-button v-if="operations.isShow" :type="operations.btnType"  :icon="`iconfont ${operations.icon}`"
                       @click="screenBtn(operations)" class="screen-btn" :disabled="operations.disabled"
                       size="mini">{{operations.label}}
            </el-button>
                    </span>
        </li>
      </ul>
    </div>
</template>

<script>
  export default {
    name: "PublicFilter",
    props: {
      screenConfig: {
        type: Object,
        required: true
      },
    },
    data() {return {};
    },
    methods: {
      // 操作按钮
      screenBtn(data) {this.$emit("screenBtn",data)
      }
    },
  }
</script>

<style scoped lang="less">
.screen-btn {margin-right: 10px;}
.row-list {
  li{
    margin-bottom: 15px;
    float: left;
    margin-right: 15px;
    min-height: 32px;
    line-height: 32px;
  }
}
</style>

4、表格组件代码

<template>
  <div>
    <el-table size="medium" :data="tableData" :stripe="false" :border="false" :fit="true"
              :header-cell-style="{background:columnObj.headerBgColor,color: columnObj.headerColor,height: columnObj.headerHigh}"
              :highlight-current-row="columnObj.highlight" :row-class-name="tableRowClassName"
              @row-click="rowClick" :row-style="tableRowStyle"  @sort-change="sortChange">
      <!-- 抉择框是否开启,selectable 管制是否单行禁用 -->
      <el-table-column v-if="columnObj.selection" type="selection" :selectable="selectable" :align="columnObj.align ||'center'"></el-table-column>
      <el-table-column v-if="columnObj.serialNumber" type="index" label="序号" :align="columnObj.align ||'center'"width="50"></el-table-column>
      <!-- 一般列 -->
      <el-table-column v-for="(column,columIndex) in columnObj.columnData" :key="columIndex" :prop="column.prop"
                       :label="column.label" :width="column.width" :fixed="column.fixed" :align="columnObj.align ||'center'":sortable="column.sortable":index="columIndex" show-overflow-tooltip>
        <template slot-scope="{row,$index}">
          <!-- 默认展现 -->
          <span v-if="column.type =='text'":style="{color:row[column.colorName]}">
            {{row[column.prop]}}
          </span>
          <!-- 标签类型 -->
          <span v-if="column.type =='tag'">
            <el-tag :type="row[column.tagType]">{{row[column.prop]}}</el-tag>
          </span>
          <!-- 自定义内容 -->
          <slot v-if="column.type =='ownDefined'"name='ownDefined':row="row,column"></slot>
          <!-- switch 开关 -->
          <el-switch v-if="column.type =='switch'"v-model="row[column.prop]":inactive-text="row[column.prop] ? column.openText:column.closeText"@change="switchChange(row,$index,column.prop)"></el-switch>
          <!-- 图片展现 -->
          <el-image v-if="column.type =='image'"style="width: 50px; height: 50px":src="row[column.prop]"fit="cover":preview-src-list="[row[column.prop]]"></el-image>
<!--          url-->
          <div v-if="column.type =='url'">
            <a v-if="row[column.urlName]" :href="row[column.urlName]"  target="_blank" class="url">{{row[column.prop]}}</a>
            <span v-else>{{row[column.prop]}}</span>
          </div>
          <!-- 可编辑 -->
          <el-input v-if="column.type =='editRow'"v-model="row[column.prop]":disabled="row[column.editRow]"@blur="editInputBlur(row,$index,column.prop,columIndex)"size="mini"></el-input>
<!--           自定义操作按钮,每行不一样 -->
          <span v-if="column.type =='customAction'"v-for="(operations, index) in row[column.prop]":key="index">
                        <el-button v-if="operations.isShow" type="text"
                       @click="rowOperation(row,$index,operations.type)" :style="{color:operations.color}"
                       size="small">{{operations.label}}
            </el-button>
                    </span>
<!--           惯例操作按钮 -->
          <span v-if="column.type =='routineAction'"v-for="(operations, index) in column.operation":key="index">
                        <el-button v-if="operations.isShow" type="text"
                       @click="rowOperation(row,$index,operations.type)" :style="{color:operations.color}"
                       size="small">{{operations.label}}
            </el-button>
                    </span>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <div class="page_div" :style="{textAlign: pageObj.position ||'center'}" v-if="pageObj.show">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                     :hide-on-single-page="false" :current-page="pageObj.pageNo" :pager-count="7"
                     :page-sizes="[10, 15, 20, 30,50]" :page-size="pageObj.pageSize" background
                     layout="total,sizes,prev, pager, next" :total="pageObj.total">
      </el-pagination>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'public-table',
    props: {
      tableData: {
        type: Array,
        required: true
      },
      columnObj: {
        type: Object,
        required: true
      },
      pageObj: {
        type: Object,
        required: true
      }
    },
    data() {return {}
    },
    methods: {
      // 管制单行是否可用
      selectable(row, index) {if (row.switchs) {return true;}
        this.$emit("selectable", row, index)
      },
      // 操作按钮
      rowOperation(row, $index, now) {this.$emit("rowOperation", row, $index, now)
      },
      // switchChange 调用
      switchChange(row, $index, prop) {this.$emit("switchChange", row, $index, prop);
      },
      // 行款式
      tableRowStyle({row}) {if(row.styleData) {return {'background': `${row.styleData.bgColor}`,'color':`${row.styleData.fontColor}`};
        }
      },
      // 行的 className 的回调办法
      tableRowClassName({row, rowIndex}) {row.rowIndex = rowIndex;},
      // 点击行
      rowClick(row, column, event) {this.$emit("rowClick", row, column, event);
      },
      // 可编辑 input 失去焦点
      editInputBlur(row, $index, prop, columIndex) {this.$emit('editInputBlur', row, $index, prop, columIndex);
      },
      // 近程排序
      sortChange({column, prop, order}) {
        // ascending 上    descending 下
        this.$emit('sortChange', column, prop, order);
      },
      // 条数变动
      handleSizeChange(e) {this.$emit('handleSizeChange', e);
      },
      // 页码变动
      handleCurrentChange(e) {this.$emit('handleCurrentChange', e);
      }
    }
  }
</script>
<style lang="less" scoped>
  .el-button {margin: 0 6px;}
  .page_div {padding: 15px 0;}
  .url {
    color: #3d8de0;
    cursor: pointer;
  }
  /deep/.el-table__body tr.current-row>td.el-table__cell {background-color: #a8b9cc;}
  /deep/.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {color: #606266;}
</style>

5、全局引入组件

**main.js** 页面全局引入组件或单页面引入看需要,我是全局引入

import {PublicTable,PublicFilter} from '@/components';

Vue.component(PublicTable.name,PublicTable);
Vue.component(PublicFilter.name,PublicFilter);

文件目类
[图片上传失败 …(image-70848a-1662602567621)]
components>index.js

import PublicTable from '@/components/PublicTable';
import PublicFilter from '@/components/PublicFilter';

export {PublicTable,PublicFilter};

6、父组件应用

<template>
  <div class="box">
    <el-card shadow="never">
      <public-filter :screenConfig="screenConfig" @screenBtn="screenBtn">
        <template  slot='customFilter'>
          <el-radio-group v-model="screenConfig.searchParams.aaa" class="radio">
            <el-radio :label="3"> 备选项 </el-radio>
            <el-radio :label="6"> 备选项 </el-radio>
            <el-radio :label="9"> 备选项 </el-radio>
          </el-radio-group>
        </template>
      </public-filter>
    </el-card>
    <el-card shadow="never" class="mt-20">
      <public-table :tableData="tableData" :columnObj="columnObj" :pageObj="pageObj" @rowOperation="rowOperation"
                   @switchChange="switchChange" @editInputBlur="editInputBlur" @rowClick="rowClick"
                    @sortChange="sortChange"
                   @handleSizeChange="handleSizeChange" @handleCurrentChange="handleCurrentChange">
        <template slot='ownDefined' slot-scope="{row,column}">
          <p>
            <span v-if="row.names" :class="`iconfont ${row.names.icon}`" :style="{fontSize: row.names.fontSize,color: row.names.color}"></span>
            {{row.name}}
          </p>
          <p>{{row.address}}</p>
        </template>
      </public-table>
    </el-card>
  </div>
</template>
<script>

  export default {data() {
      return {
        // 筛选配置
        screenConfig:{
          searchShow: true, // 筛选是否显示
          formItem: [{
            type: "input",
            prop:'input',
            label: "姓名",
            placeholder:'请输出姓名'
          }, {
            type: "select",
            prop: "parkingType",
            label: "类型",
            value:"id",
            leftLabel:"name",
            rightLabel:"gender",
            multiple: false,
            filterable: true,
            options: [{
              id: '1',
              name: '张三',
              gender: '男',
            },{
              id: '2',
              name: '李四',
              disabled: true
            },{
              id: '3',
              name: '李四',
              gender: '女',
            }],
            placeholder:'请抉择数据'
          }, {
            type: "datePicker",
            prop: "data",
            label: "导出工夫",
            format: "yyyy-MM-dd", // 数据格式 'yyyy-MM-dd'、timestamp(工夫戳)dateType: "datetimerange", // 显示类型(罕用类型 daterange、date、datetime)year 年、month 月、date 日期、dates 多个日期、week 周、datetime 日期和工夫点、datetimerange 日期和工夫范畴、daterange 日期范畴、monthrange 月份范畴
            placeholder: '请抉择',
          }, {
            type: "custom",
            prop: "aaa",
            label: "自定义筛选",
          }, {
            type: "operationBtn",
            prop: "data",
            operation: [{
              btnType: "primary", //primary 蓝色、success 绿色、warning 橘黄、danger 红色、info 灰色、text 文本
              type: 'cx',
              label: "查问",
              isShow: true,
              disabled: false,
              icon: 'icon-cry',
            },{
              btnType: "danger", //primary 蓝色、success 绿色、warning 灰色、danger 橘黄、info 红色、text 文本
              type: 'cz',
              label: "重置",
              isShow: true,
              disabled: true,
              icon:'icon-atm-away'
            }]
          }]
        },
        // 表头配置
        columnObj: {
          selection: true,// 抉择框
          serialNumber: true,// 序号
          highlight: false,// 以后行是否高亮
          align: 'center',// 对齐形式
          headerBgColor: '',// 表头背景色
          headerColor: '',// 表头字体色彩
          headerHigh: '55px',// 表头高
          // columnObj
          // selection(是否有多选框):true 显示,false 暗藏
          // serialNumber(是否有序列号):true 显示,false 暗藏
          // align(行文字对其形式):left 左,right 右,center 居中
          // highlight(以后行是否高亮)
          // headerColor(表头字体色彩)
          // headerHigh(表头高): 小于 55px 没有成果
          // columnObj>columnData
          //type(列类型):text 文本,ownDefined 自定义,switch 开关,url 链接,editRow 可编辑,image 图片,customAction 自定义操作,routineAction 惯例操作
          //prop(参数),label(列名),width(宽度)
          //sortable(是否反对排序):true 开启排序,false 敞开排序 'custom' 近程排序
          //openText,closeText(开关开启 / 敞开名称),urlName(url 地址对应参数):参数为空时只展现文字不可跳转
          //editRow(以后行是否可编辑和 type 为 editRow 对应):false 可编辑,true 不可编辑
          //colorName 管制文字色彩字段名
          columnData: [{
            type:'text',
            prop: "school",
            label: "默认款式",
            width: "",
            colorName: "color",
          }, {
            type:'tag',
            prop: "tag",
            tagType: "tagType",
            label: "标签类型",
            width: "",
          }, {
            type:'text',
            prop: "id",
            label: "能够排序",
            width: "",
            sortable: true,
          }, {
            type:'ownDefined',
            prop: "aaa",
            label: "自定义内容",
            width: "",
          }, {
            type:'switch',
            prop: "switchs",
            label: "switch 开关",
            width: "",
            openText: "关上", //type='switch' 关上时的文字描述
            closeText: "敞开", //type='switch' 敞开时的文字描述
          }, {
            type:'url',
            prop: "name2",
            label: "可跳转",
            urlName: "url", //type='url', 跳转地址名称(按需返回)width: "",
          }, {
            type:'editRow',
            prop: "name",
            label: "可编辑",
            width: "",
            editRow: 'editRow',
          },{
            type:'image',
            prop: "img",
            label: "图片",
            width: "",
          }, {
            type:'customAction',
            label: "自定义操作",
            width: "180",
            prop: "operation",
          }, {
            type:'routineAction',
            label: "惯例操作",
            width: "180",
            operation: [{
              type: "cg",
              label: "惯例",
              color: '',
              isShow: true,
            }]
          }],
        },
        // 表格数据
        // editRow(可编辑行是否可操作 true/false)
        // styleData(Object 类型,行款式, 背景色、字体色彩等)
        //operation(Array 类型,表头 type=‘customAction’时按钮配置):type 类型,label 按钮名,color 按钮色彩,isShow 是否显示(true/false),// tagType 标签类型(success 绿 /info 灰 /warning 橘黄 /danger 红 /)返回空为默认值蓝色
        tableData: [{
          id: '1',
          school: '北京大学',
          name: '王小虎',
          tag: '标签一',
          tagType: 'success',
          names:{
            name: '王小虎',
            icon:'icon-phone',
            fontSize: '15px',
            color:"red",
          },
          editRow: true,
          address: '上海市普陀区金沙江路 1518 弄',
          switchs: true,
          img: '',
          name2: '张三',
          icon: 'icon-phone',
          // 行款式
          styleData: {
            bgColor: '#878787',
            fontColor: '#fff',
          },
          operation: [{
            type: "edit",
            label: "编辑",
            color: '#be147d',
            isShow: true,
          }, {
            type: "delete",
            label: "删除",
            color: 'red',
            isShow: false,
          }, {
            type: "see",
            label: "查看",
            color: '#d77000',
            isShow: true,
          }],
        }, {
          id: '2',
          school: '天津大学',
          name: '王小虎',
          tag: '标签二',
          tagType: '',
          names:{
            name: '王小虎 2',
            icon:'icon-cry',
            fontSize: '18px',
            color:"blue",
          },
          address: '上海市普陀区金沙江路 1517 弄',
          switchs: true,
          img: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
          name2: '李四',
          url:'https://www.baidu.com/',
        }, {
          id: '3',
          school: '北京体育',
          tag: '标签三',
          tagType: 'info',
          color: 'red',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄',
          switchs: false,
          name2: '王五',
          img: '',
          operation: [{
            type: "edit",
            label: "编辑",
            color: '#67C23A',
            isShow: true,
          }, {
            type: "delete",
            label: "删除",
            color: 'red',
            isShow: true,
          }, {
            type: "see",
            label: "查看",
            color: '',
            isShow: true,
          }]
        }, {
          id: '4',
          school: '河北师范大学',
          name: '王小虎',
          tag: '标签四',
          tagType: 'warning',
          address: '上海市普陀区金沙江路 1516 弄',
          switchs: true,
          name2: '赵六',
          url:'https://www.baidu.com/',
          img: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
        }],
        // 分页配置
        pageObj: {
          show: true, // 是否显示
          position: "right", // 地位
          total: 100,
          pageNo: 1,
          pageSize: 10
        },
      }
    },
    created(){this.$set(this.screenConfig,'searchParams',{})
    },
    methods: {screenBtn(data) { },
      rowOperation(row, $index, now) {console.log(row, $index, now)
      },
      switchChange(row, $index, prop) {console.log(row, $index, prop)
      },
      rowClick(row, column, event) {
        // 点击行触发,编辑点击的所在列,排除 selection 抉择框
        // if (column.type != 'selection') {//   this.columnObj.columnData[column.index].editRow = row.rowIndex;
        // }
      },
      sortChange(column, prop, order) {// console.log(column, prop, order)
      },
      editInputBlur(row, $index, prop, columIndex) {// console.log(row, $index, prop, columIndex)
        // this.columnObj.columnData[columIndex].editRow = -1;
      },
      // 页码变动
      handleCurrentChange(e) {this.pageObj.pageNo = e;},
      // 条数变动
      handleSizeChange(e) {
        this.pageObj.pageSize = e;
        this.pageObj.pageNo = 1;
      },
    },
  }
</script>
<style>
.box {
  background: #f4f4f4;
  padding: 2% 1%;
  box-sizing: border-box;
}
</style>

正文完
 0