element-ui table組件化,重新封裝

1、話不多說先看效果

主要實現功能:篩選:輸入框、下拉框、時間;表格適用:多選、序號、排序、自定義、開關、鏈接可跳轉、輸入框、圖片、自定義操作按鈕(部分頁面需要每行顯示按鈕不用所以大家按需添加)、常規操作按鈕(每行操作按鈕都相同無其他需求)、設置行背景色、分頁

d8064cea29774f3fbb10fe2a6b59b01c.png

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>


?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容