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>