ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

el-table二次封装

2022-09-06 19:01:10  阅读:206  来源: 互联网

标签:el 封装 val default console return table type row


<template>
  <div style="margin: 20px 20px 100px 20px">
    <el-table
      border
      class="customer-no-border-table"
      element-loading-text="数据正在加载中..."
      :row-class-name="tableRowClassName"
      :header-cell-style="{ background: '#E7F2FD', color: '#252525' }"
      style="width: 100%; border-top: 1px solid #409eff"
      v-loading="loading"
      :ref="tableName"
      :data="tableData"
      :highlight-current-row="light"
      @row-click="getrow"
      @sort-change="sortChange"
      @selection-change="handleSelectionChange"
      :row-key="rowKey"
      :reserve-selection="reserve"
      :max-height="fixedHeight > 0 ? fixedHeight : tableHeight - difference"
    >
      <!-- 复选框 -->
      <el-table-column
        type="selection"
        v-if="choice"
        width="50"
        :align="headerAlign"
        :key="Math.random()"
      >
      </el-table-column>
      <!-- 序号 -->
      <el-table-column
        label="序号"
        v-if="serialNumber"
        width="50"
        type="index"
        :align="headerAlign"
        :key="Math.random()"
      >
      </el-table-column>
      <!-- 动态表头 -->
      <!-- {
                prop:'title',// 列表渲染的字段key
                label:'菜单名称',// 字段中文名称
                align:''// 列表内容文字的位置
                sort:true, // 是否排序
                form:'string', (可选:string/img/Button/filter/select)
                key:{label: "label",value: "value"} // 这个配置是下拉框的form = select
                filter(row){},// 对数据进行过滤 并返回内容 和vue 过滤器一样的功能
                configure:{ // 配置按钮的参数对象
                    type:''// 参考el-button 官网参数
                    size:''// 参考el-button 官网参数
                },
                callback(row){} //点击按钮的回调函数
            } -->
      <div v-for="(item, index) in tableLabel" :key="index">
        <!-- 普通数据展示/或者字符串文本展示 -->
        <el-table-column
          v-if="!item.form || item.form === 'string'"
          :prop="item.prop"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
          show-overflow-tooltip
        >
        </el-table-column>
        <!-- 数据过滤:根据filter函数自定义规则进行数据返回 -->
        <el-table-column
          v-else-if="item.form === 'filter'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            {{ item.filter(scope.row) }}
          </template>
        </el-table-column>
        <!-- 图片展示 -->
        <el-table-column
          v-else-if="item.form === 'img'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
        >
          <template slot-scope="scope">
            <!-- 如果是字符串就是一个图片 -->
            <div v-if="typeof scope.row[item.prop] === 'string'">
              <el-image
                style="width: 22px; height: 22px"
                :src="scope.row[item.prop] ? scope.row[item.prop] : defaultImg"
                :preview-src-list="[
                  scope.row[item.prop] ? scope.row[item.prop] : defaultImg,
                ]"
              >
              </el-image>
            </div>
            <!-- 不是字符串就统一数组来处理 -->
            <div
              v-else-if="
                scope.row[item.prop] !== null && scope.row[item.prop].length > 0
              "
            >
              <span
                v-for="(item1, index1) in scope.row[item.prop]"
                :key="index1"
              >
                <el-image
                  style="width: 22px; height: 22px; margin-right: 20px"
                  :src="scope.row[item.prop][index1]"
                  :preview-src-list="scope.row[item.prop]"
                  :z-index="2100"
                >
                </el-image>
              </span>
            </div>
          </template>
        </el-table-column>
        <!-- 按钮展示 -->
        <el-table-column
          v-else-if="item.form === 'Button'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
        >
          <template slot-scope="scope">
            <el-button
              @click="item.callback && item.callback(scope.row)"
              :type="
                item.configure && item.configure.type ? item.configure.type : ''
              "
              :size="
                item.configure && item.configure.size ? item.configure.size : ''
              "
            >
              {{ item.configure.text || "缺少按钮文字" }}</el-button
            >
          </template>
        </el-table-column>
        <!-- 多个复选框 -->
        <el-table-column
          v-else-if="item.form === 'checkbox'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
        >
          <template slot-scope="scope">
            <span
              style="margin-left: 5px"
              v-for="(v, i) in scope.row.authority"
              :key="i"
            >
              <el-checkbox
                :label="v.name"
                name="type"
                v-model="v.open"
              ></el-checkbox>
            </span>
            <span v-if="scope.row.authority && scope.row.authority.length < 1"
              >暂无</span
            >
          </template>
        </el-table-column>
        <!-- 单选框 -->
        <!-- 表头配置tableLabel -->
        <!-- {
                        prop: 'timeType',最终下拉框每次选中的值都绑定到 这个定义的字段上
                        label: '时间单位',
                        align: 'center',
                        form: "radio",
                        key: {
                            label: "label",
                            value: "value"
                        },
                        width: 250,
                    }, -->
        <!-- 列表循环数据 每一项必须要有 radioList属性为数组 -->
        <el-table-column
          v-else-if="item.form === 'radio'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
        >
          <template slot-scope="scope">
            <div v-if="scope.row.radioList && scope.row.radioList.length">
              <el-radio-group v-model="scope.row[item.prop]">
                <el-radio
                  v-for="items in scope.row.radioList"
                  :key="items[item.key.value]"
                  :label="items[item.key.value]"
                  >{{ items[item.key.label] }}</el-radio
                >
              </el-radio-group>
            </div>
            <div v-else>
              <span style="color: #e6a23c">缺少radioList属性数组!</span>
            </div>
          </template>
        </el-table-column>
        <!-- 下拉框 -->
        <!-- 表头配置tableLabel -->
        <!-- {
                    prop:'xxx' 最终下拉框每次选中的值都绑定到 这个定义的字段上
                    form:'select',
                    key:{label: "label",value: "value"}
                } -->
        <!-- 列表循环数据 每一项必须要有 options属性为数组 -->
        <el-table-column
          v-else-if="item.form === 'select'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'left'"
          :key="index"
        >
          <template slot-scope="scope">
            <el-select
              v-model="scope.row[item.prop]"
              placeholder="请选择"
              size="mini"
            >
              <el-option
                v-for="items in scope.row.options"
                :key="items[item.key.value]"
                :label="items[item.key.label]"
                :value="items[item.key.value]"
              >
              </el-option>
            </el-select>
          </template>
        </el-table-column>
        <!-- 输入框 -->
        <el-table-column
          v-else-if="item.form === 'input'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'left'"
          :key="index"
        >
          <template slot-scope="scope">
            <el-input
              placeholder="请输入内容"
              v-model="scope.row[item.prop]"
              size="mini"
            >
            </el-input>
          </template>
        </el-table-column>
        <!-- 自定义 -->
        <el-table-column
          v-else-if="item.form === 'my'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <span
              style="text-decoration: underline; color: blue"
              @click="item.callback(Object.assign({}, scope.row))"
              >{{ item.filter(scope.row) }}</span
            >
          </template>
        </el-table-column>
        <!-- 固定列 -->
        <el-table-column
          v-else-if="item.form === 'fixed'"
          :width="item.width"
          :label="item.label"
          :sortable="item.sort"
          :align="item.align ? item.align : 'center'"
          :key="index"
        >
        </el-table-column>
      </div>

      <el-table-column
        label="操作"
        :width="operation.width"
        v-if="JSON.stringify(operation) !== '{}'"
      >
        <template slot-scope="scope">
          <!-- 操作按钮 -->
          <!-- {
                        label:'删除',
                        type:'danger',// 按钮类型  参考el-button 官网参数
                        size:"mini", // 按钮大小  参考el-button 官网参数
            plain:true, // 是否朴素按钮
                        callback(row){}, // 点击按钮回调函数
                        disabled(row){ return true/false} //是否禁用 可以条件判断 让函数返回布尔值
                        authority:true// 如果涉及到权限按钮控制的 就添加这个属性(false普通按钮/true权限按钮)
                        authorityEvent(row){return true/false}
                    } -->
          <!-- 动态操作按钮 -->
          <div class="flex center">
            <div
              class="flex center"
              v-for="(item, index) in operation.Button"
              :key="index"
            >
              <el-button
                style="margin: 0 5px"
                v-if="!item.authority"
                @click="item.callback(Object.assign({}, scope.row))"
                :type="item.type ? item.type : ''"
                :size="item.size ? item.size : ''"
                :disabled="item.disabled && item.disabled(scope.row)"
                :plain="plain"
                >{{ item.label }}</el-button
              >
              <el-button
                style="margin: 0 5px"
                v-else-if="
                  item.authority &&
                  item.authorityEvent &&
                  item.authorityEvent(item.label)
                "
                @click="item.callback(Object.assign({}, scope.row))"
                :type="item.type ? item.type : ''"
                :size="item.size ? item.size : ''"
                :disabled="item.disabled && item.disabled(scope.row)"
                :plain="plain"
                >{{ item.label }}</el-button
              >
            </div>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <div
      style="padding: 10px"
      v-if="paging"
      :style="{ 'text-align': pagingPosition }"
    >
      <el-pagination
        @size-change="handleNumberChange"
        @current-change="handleCurrentPage"
        :current-page="searchData.page"
        :page-sizes="[10, 15, 20, 30, 40, 50]"
        :page-size="searchData.limit"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
      >
      </el-pagination>
    </div>
  </div>
</template>

<!-- /**
 * 组件说明
 * 属性:
 * 参数                     说明                           类型                    默认值
 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 * tableData              列表 的数据源                   Array                      []
 * treeProps              支持树类型的数据的列表显示       Object                     {children: 'children'}
 * rowKey                 树类型的数据 列表必须要指定        String                     '_id'
 * serialNumber           是否需要序号                     Boolean                    true
 * headerAlign               表头对齐方式/复选框/序号              String                    'left'/'center'/'right'
 * tableLabel               动态表头渲染数组                Array                     []
 * choice                   是否开启多选复选框                Boolean                 false
 * operation               操作列表按钮                    Object                     {}
 * total                   分页总页数                     number                     0
 * paging                   是否开启分页                     Boolean                 false
 * pagingPosition           分页底部的位置                     String                     'left'/'center'/'right'
 * fixedHeight               固定table列表高度                 number                      0
 * pagingPage               分页参数                         Object                     {pageSize: 20,page: 1}
 * headButton             列表头部按钮是否显示              Boolean                   false

 * 回调事件:
 * select  获取复选框选中对象 返回数组
 * sortChange     获取当前点击表头指定排序结果
 * handleCurrentPage     每次切换页数触发并且回调页数
 * handleNumberChange     每次切换展示的条数触发并且回调
 */ -->
<script>
const defaultImg = require("../assets/nodata.png");
export default {
  props: {
    // ref的名字
    tableName: {
      type: String,
      default: "",
    },
    // 是否记忆分页选中行
    reserve: {
      type: Boolean,
      default: false,
    },
    // 是否高亮当前行
    ligth: {
      type: Boolean,
      default: false,
    },
    // 是否朴素按钮
    plain: {
      type: Boolean,
      default: true,
    },
    // 数据
    tableData: {
      type: Array,
      default: () => [],
    },
    // 支持树类型的数据的显示
    treeProps: {
      type: Object,
      default: () => ({
        children: "children",
      }),
    },
    //树类型的数据 列表必须要指定row-key id
    rowKey: {
      type: String,
      default: "_id",
    },
    // 是否需要序号
    serialNumber: {
      type: Boolean,
      default: true,
    },
    // 表头对齐方式
    headerAlign: {
      type: String,
      default: "center",
    },
    // 表头
    tableLabel: {
      type: Array,
      default: () => [],
    },
    // 复选框
    choice: {
      type: Boolean,
      default: false,
    },
    // 操作按钮参数
    operation: {
      type: Object,
      default: () => ({}),
    },
    // 总条数
    total: {
      type: Number,
      default: 0,
    },
    //分页
    paging: {
      type: Boolean,
      default: false,
    },
    // 分页组件位置
    pagingPosition: {
      type: String,
      default: "left",
    },
    // 固定高度
    fixedHeight: {
      type: Number,
      default: 0,
    },
    // 分页组件参数
    pagingPage: {
      type: Object,
      default: () => ({
        limit: 10,
        page: 1,
      }),
    },
    // 设置偏移高度(到达每个页面不同内容高度,都可以让列表高度填充满整个可视区)
    difference: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      defaultImg: defaultImg,
      tableHeight: document.documentElement.clientHeight - (70 + 80), // 表格自适应高度 默认撑满
      // 分页固定参数
      searchData: {
        limit: this.pagingPage.limit,
        page: this.pagingPage.page,
      },
    };
  },
  methods: {
    tableRowClassName({ rowIndex }) {
      if (rowIndex % 2 === 1) {
        return "success-row";
      }
      return "";
    },

    // 重置分页参数
    pagingReset(limit, page) {
      if (!limit && !page) {
        this.searchData.limit = 10;
        this.searchData.page = 1;
      } else if (limit) {
        this.searchData.limit = limit;
      } else {
        this.searchData.page = page;
      }
    },
    // 切换页数
    handleCurrentPage(val) {
      this.searchData.page = val;
      this.$emit("handleCurrentPage", val);
    },
    // 每页N展示条
    handleNumberChange(val) {
      this.searchData.limit = val;
      this.$emit("handleNumberChange", val);
    },
    //选中当前行
    getrow(row) {
      this.$emit("getrow", row);
    },
    // 复选框勾选
    handleSelectionChange(array) {
      console.log(array, "array");
      this.$emit("handleSelectionChange", array);
    },
    // 排序
    sortChange(column, prop, order) {
      console.log(column, "column");
      console.log(prop, "prop");
      console.log(order, "order");
      this.$emit("sortChange", column);
    }
  },
};
</script>
<style scoped lang='less'>
/* 默认el-table 行高过于高,这里设置减少padding之间的间距 */
/deep/ th {
  padding: 9px 0;
}

/deep/ .el-table td {
  padding: 9px 0;
}
</style>

  

<template>
  <div>
    <table-List
      :tableData="tableData"
      :tableLabel="tableLabel"
      :choice="choice"
      :light="light"
      :reserve="reserve"
      :paging="paging"
      :operation="operation"
      :total="total"
      pagingPosition="center"
      headerAlign="center"
      @sortChange="sortChange"
      @getrow="getrow"
      @handleSelectionChange="handleSelectionChange"
      @handleNumberChange="handleNumberChange"
      @handleCurrentPage="handleCurrentPage"
    >
    </table-List>
  </div>
</template>

<script>
import tableList from "./table.vue";
export default {
  components: {
    tableList,
  },
  data() {
    return {
      light: true, //高亮当前行
      paging: true, //是否分页
      pagingPage: {
        limit: 10,
        page: 1,
      },
      tableData: [
        { nickName: "111", friendCount: 123 },
        { nickName: "222", friendCount: 456 },
      ], //数据源
      tableLabel: [
        {
          prop: "nickName",
          label: "用户昵称",
          align: "center",
          form: "filter",
          filter(row) {
            if ((row.nickName = "111")) {
              return `丫丫`;
            } else {
              return "哈哈";
            }
          },
        },
        {
          prop: "friendCount",
          label: "好友数量",
          align: "center",
          form: "my",
          filter(row) {
            if (row.friendCount == "123") {
              return `百度`;
            } else {
              return "billbill";
            }
          },
          callback: (row) => {
            if (row.friendCount == "123") {
              window.open("https://www.baidu.com/?tn=02003390_19_hao_pg");
            } else {
              window.open("https://blog.csdn.net/jlsdzhj/article/details/80647682");
            }
          },
        },
      ],
      operation: {
        width: "220",
        Button: [
          {
            label: "查看",
            size: "mini",
            authority: false,
            callback(k) {
              console.log(k);
            },
          },
        ],
      },
      total: 0,
    };
  },
  methods: {
    // 分页
    handleNumberChange(val) {
      console.log(val, "当前页码");
    },
    // 每一页展示多少条切换
    handleCurrentPage(val) {
      console.log(val, "当前展示条数");
    },
    // 排序
    sortChange(column) {
      console.log(column, "column");
    },
    //多选
    handleSelectionChange(array) {
      console.log(array, "array");
      this.selectList = array;
    },
    // 单选
    getrow(row) {
      console.log(row, "选中行");
      this.trData = row;
    },
  },
};
</script>

<style lang="scss" scoped>
</style>





components:{tableList,
},
data(){
    return{
        tableData: [
        {nickName:"111",friendCount:123,},{nickName:"222",friendCount:456},{}],//数据源
        tableLabel:[
            {
            prop: 'nickName',
            label: '用户昵称',
            align: 'center',
            form:'filter',
            filter(row){
              if(row.nickName='111'){
                return '丫丫'
              }else{
                return '哈哈'
              }
            }
          },
           {
            prop: 'friendCount',
            label: '好友数量',
            align: 'center',
          },
        ],
        operation:{
            width: '220',
            Button:[
             {
                  label: '查看',
                  size: "mini",
                  authority: false,
                  callback(k) {
                        console.log(k)
                  }
                }
            ]
        },
        total:10,
        
    }
} ,
methods:{
    handleNumberChange(val){},// 每一页展示多少条切换
    handleCurrentPage(val){},//切换分页
    sortChange(column){},// 排序
    select(valArr){},//列表复选框
}             

  

标签:el,封装,val,default,console,return,table,type,row
来源: https://www.cnblogs.com/hxy--Tina/p/16662976.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有