二次封装el-table组件

二次封装el-table组件

element-ui不同于其他的ui框架,table的字段可以传入一个数组就可以,而是每次都需要写结构 所以想自己封装一个像其他ui框架的组件,方便自己使用。也为了可以偷懒

先简单封装分页器

<template>
    <div style="display: flex;justify-content: space-between;margin: 10px">
        <div class="legend">
            <!-- 左边的提示内容 -->
            <slot></slot>
        </div>
        <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :page-sizes="pageSizes || [12, 20, 30, 40]"
                :page-size="listQuery.limit"
                :current-page="listQuery.page"
                :pager-count="pagerCount"
                :layout="layout"
                :total="count">
        </el-pagination>
    </div>
</template>

<script>
    export default {
        name: "Pagination",
        props: {
            listQuery: {
                type: Object,
                default: ()=>{}
            },
            count: {
                type: Number,
                default: 0
            },
            pagerCount: {
                type: Number,
                default: 7
            },
            layout:{
                type: String,
                default: 'total, sizes, prev, pager, next, jumper'
            },
            pageSizes:{
                type:Array,
                default:[12, 20, 30, 40]
            }
        },
        data: () => ({

        }),
        methods: {
            handleSizeChange(v){
                let listQuery = this.listQuery
                listQuery.limit = v
                this.$emit('update:listQuery',listQuery)
                this.$emit('getList')

            },
            handleCurrentChange(v){
                let listQuery = this.listQuery
                listQuery.page = v
                this.$emit('update:listQuery',listQuery)
                this.$emit('getList')
            }
        }
    }
</script>

封装el-table (暂时兼容二级表头 后面再兼容多层)

主要利用
$listeners https://v2.cn.vuejs.org/v2/api/#vm-listeners
$attrs https://v2.cn.vuejs.org/v2/api/#vm-attrs
v-slot https://v2.cn.vuejs.org/v2/api/#v-slot

<template>
  <div id="renderTable">
    <el-table v-bind="$attrs" :data="data" class="table" v-on="$listeners">
      <template #default>
        <el-table-column
          v-for="item in columns"
          v-bind="item"
          :header-align="item.headerAlign || 'center'"
          :align="item.align || 'center'"
          :key="item.prop"
        >
          <template
            v-if="item.slot && !item.children"
            v-slot="{ row, column, $index }"
          >
            <slot :name="item.prop" v-bind="{ row, column, $index }"></slot>
          </template>
          <el-table-column
            v-for="jtem in item.children"
            :header-align="jtem.headerAlign || 'center'"
            :align="jtem.align || 'center'"
            :key="jtem.prop"
            v-bind="jtem.slot ? dealSlot(jtem) : jtem"
          >
            <template v-if="jtem.slot" v-slot="{ row, column, $index }">
              <slot :name="jtem.prop" v-bind="{ row, column, $index }"></slot>
            </template>
          </el-table-column>
        </el-table-column>
      </template>
    </el-table>
    <Pagination
      v-if="paging"
      :listQuery.sync="listQuery"
      :count.sync="count"
      v-on="$listeners"
    ></Pagination>
  </div>
</template>

<script>
export default {
  name: "renderTable",
  inheritAttrs: false,
  props: {
    columns: {
      type: Array,
      required: true,
    },
    data: {
      type: Array,
      required: true,
    },
    paging: {
      type: Boolean,
      default: false,
    },
    listQuery: {
      type: Object,
    },
    count: {
      type: Number,
    },
  },
  methods: {
    dealSlot(obj) {
    	//深克隆的方法可以自己处理
      let res = this.$deepClone(obj)
      delete res.slot
      return res
    },
  },
}
</script>
<style lang="scss" scoped>
table {
  width: 100%;
}
</style>

import App from "./App.vue"
import router from "./router"
import store from "./store"
const Pagination = () => import("./components/Pagination")
const renderTable = () => import("./components/table/renderTable")

Vue.component("Pagination", Pagination) // 注册分页组件
Vue.component("renderTable", renderTable) // 注册表格组件

使用

<template>
  <div class="table">
    <renderTable
      :data="tableData"
      :columns="columns"
      :border="true"
      :stripe="true"
      v-loading="loading"
      :paging="true"
      :listQuery.sync="listQuery"
      :count.sync="count"
      @getList="getList"
    >
      <template #order="{ $index }">
        <span> {{ (listQuery.page - 1) * listQuery.limit + $index + 1 }}</span>
      </template>
      <template #sex="{ row }">
        <span> {{ row.sex ? "男" : "女" }}</span>
      </template>
      <template #merry="{ row }">
        <span> {{ row.merry ? "已婚" : "未婚" }}</span>
      </template>
    </renderTable>
  </div>
</template>
<script>
export default {
  data() {
    return {
      listQuery: {
        vagueSearch: "",
        dateArr: [],
        page: 1,
        limit: 12,
      },
      count: 10,
      tableData: [
        {
          id: 1,
          name: "小明",
          sex: "1",
          age: 18,
          nation: "汉族",
          phone: "13000000000",
          merry: 0,
          address: "广州市天河区",
        },
      ],
      columns: Object.freeze([
        {prop: "order",label: "序号",width: 150,slot: true},
        {prop: "name",label: "姓名",width: 200},
        {prop: "sex",label: "性别",width: 200,slot: true},
        {prop: "age",label: "年龄",width: 200},
        {prop: "info",label: "个人信息",width: 300,
        children: [{prop: "phone",label: "手机号"},{prop: "address",label: "联系地址"}]},
        {prop: "nation",label: "民族",width: 200},
        {prop: "merry",label: "婚姻状况",width: 200,slot: true},
      ])
    }
  },
  methods: {
    getList() {},
  },
}
</script>

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值