vue3+ts 封装 el-table

 封装组件

<template>
  <div>
    <el-table
      ref="multipleTableRef"
      v-loading="loadings"
      :height="height == 0 ? null : height"
      :max-height="height == 0 ? 500 : null"
      :data="tableDetas"
      style="width: 100%"
      @selection-change="handleSelectionChange"
      @select="handleSelectChange"
      @select-all="handleSelectAllChange"
      @current-change="handleRadioChange"
    >
      <template #empty>
        <div class="empty_Block">
          <img src="@/assets/images/zanwu.png" />
          <div>暂无数据</div>
        </div>
      </template>
      <el-table-column v-if="selection" type="selection" :width="selectionWidth" align="center" fixed="left" />
      <el-table-column v-if="radios" :width="selectionWidth" align="center" fixed="left">
        <template #default="scope">
          <div class="radios_boxs">
            <el-radio v-model="checkObj.radioId" :label="scope.row[rowKey]"></el-radio>
          </div>
        </template>
      </el-table-column>
      <el-table-column v-if="serialNumber" :width="serialNumberWidth" label="序号" align="center" fixed="left">
        <template #default="scope">
          {{ scope.$index + 1 + (pageObjs.pageNum - 1) * pageObjs.pageSize }}
        </template>
      </el-table-column>
      <template v-for="(item, index) in columns" :key="index">
        <template v-if="item.slotName && item.slotName != 'action'">
          <el-table-column
            v-if="checkObj.checkArrList.indexOf(item.prop) != -1"
            :prop="item.prop"
            :fixed="item.fixed"
            :label="item.label"
            :min-width="item.width"
            show-overflow-tooltip
            align="center"
          >
            <template #default="scope">
              <slot :name="item.slotName" :data="scope.row" :index="scope.$index"></slot>
            </template>
          </el-table-column>
        </template>
        <template v-else-if="item.slotName && item.slotName == 'action'">
          <el-table-column :label="item.label" :width="item.width" align="center" fixed="right">
            <template #default="scope">
              <slot :name="item.slotName" :data="scope.row" :index="scope.$index"></slot>
            </template>
          </el-table-column>
        </template>
        <template v-else>
          <el-table-column
            v-if="checkObj.checkArrList.indexOf(item.prop) != -1"
            :prop="item.prop"
            :fixed="item.fixed"
            :label="item.label"
            :min-width="item.width"
            show-overflow-tooltip
            align="center"
          />
        </template>
      </template>
    </el-table>
    <pagination
      v-show="pageShow && pageObjss.total > 0"
      v-model:total="pageObjss.total"
      v-model:page="pageObjss.pageNum"
      v-model:limit="pageObjss.pageSize"
      :page-sizes="pageObjss.pageSizes"
      @pagination="getPagination"
    />
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, nextTick, watch, defineProps, defineEmits, defineExpose } from 'vue';

const props = defineProps({
  serialNumber: {
    type: Boolean, // 是否显示序号
    default: false
  },
  loadings: {
    type: Boolean, // 是否显示loading图
    default: false
  },
  columns: {
    type: Array as any, // 列展示行
    default: () => []
  },
  tableDetas: {
    type: Array, // 表格数据
    default: () => []
  },
  selection: {
    type: Boolean, // 是否复选
    default: false
  },
  height: {
    type: [Number, String], // 高度设置 默认给0,最大展示300高度
    default: 0
  },
  pageShow: {
    type: Boolean, // 是否展示分页
    default: false
  },
  pageObjs: {
    type: Object, // 分页配置
    default: () => {
      return { pageNum: 1, pageSize: 10, pageSizes: [10, 20, 30, 40, 50], total: 0 };
    }
  },
  radios: {
    type: Boolean, // 是否单选
    default: false
  },

  selectionWidth: {
    type: Number, // 设置复选单选宽度
    default: 50
  },
  serialNumberWidth: {
    type: Number, // 设置序号宽度
    default: 50
  },
  rowKey: {
    type: String, // 根据id回显复选状态,
    default: 'id'
  }
});

const emit = defineEmits(['paginationChanges', 'selectionChange', 'currentChange', 'selectChange', 'selectAllChange', 'radiosChange']);

const checkObj = reactive({
  checkArrList: [],
  radioId: ''
});

let pageObjss = reactive<any>({ pageNum: 1, pageSize: 10, pageSizes: [10, 20, 30, 40, 50], total: 0 });
pageObjss = props.pageObjs;

onMounted(() => {
  checkObj.checkArrList = props.columns.map((item: any) => item.prop);
});

// 点击分页
const getPagination = (val: any) => {
  console.log('点击子组件分页', val);
  emit('paginationChanges', val);
};

const multipleTableRef = ref();
// 表格单选点击
const handleRadioChange = (val: any) => {
  if (val) {
    checkObj.radioId = val[props.rowKey];
    emit('radiosChange', val);
  }
};
// 选择数据
const handleSelectionChange = (val: any) => {
  console.log(val);
  emit('selectionChange', val);
};
// 复选框点击
const handleSelectChange = (select: any, row: any) => {
  emit('selectChange', select, row);
};
// 全选框点击
const handleSelectAllChange = (all: any) => {
  emit('selectAllChange', all);
};

// 删除选中
const toggleSelection = (type: any, bol: any = false, val: any) => {
  console.log(type, bol, val);
  if (type == 'all') {
    multipleTableRef.value.clearSelection();
  } else {
    if (Array.isArray(val)) {
      val.forEach((item) => {
        setTimeout(() => {
          multipleTableRef.value.toggleRowSelection(item, bol);
        }, 300);
      });
    } else {
      setTimeout(() => {
        nextTick(() => {
          multipleTableRef.value.toggleRowSelection(val, bol);
        });
      }, 300);
    }
  }
};

// 取消单选选中
const toggleRadiosROW = (row) => {
  console.log(row);
  if (row) {
    props.tableDetas.forEach((item) => {
      if (item[props.rowKey] == row[props.rowKey]) {
        checkObj.radioId = item[props.rowKey];
      }
    });
    nextTick(() => {
      multipleTableRef.value.setCurrentRow(row);
    });
  } else {
    nextTick(() => {
      checkObj.radioId = '';
      multipleTableRef.value.setCurrentRow();
    });
  }
};

// watch(
//   () => props.loadings,
//   (newValue: any, oldValue: any) => {
//     console.log('newValue', newValue);
//     console.log('oldValue', oldValue);
//   },
//   {
//     immediate: true,
//     deep: false
//   }
// );

defineExpose({
  toggleSelection,
  toggleRadiosROW
});
</script>

<style scoped lang="scss">
.empty_Block {
  > img {
    margin-top: 20px;
  }
  > div {
    margin-top: -30px;
    margin-left: -10px;
  }
}
</style>

使用  html部分

      <myTable
        serial-number
        page-show
        :loadings="tableContent.loading"
        :columns="tableContent.column"
        :table-detas="tableContent.tableDeta"
        :page-objs="tableContent.pageObj"
        @pagination-changes="paginationChange"
      >
        <template #ssl="{ data }">
          {{ data.ssl == 0 ? '未加密' : '加密' }}
        </template>
        <template #action="{ data }">
          <el-button v-hasPermi="['anemometerTowerManage:anemometerTowerList:edit']" link type="primary" icon="Edit" @click="handleUpdate(data)"
            >修改</el-button
          >
          <el-button v-hasPermi="['anemometerTowerManage:anemometerTowerList:sync']" link type="success" icon="Tickets" @click="handleSync(data)"
            >数据同步</el-button
          >

          <el-button v-hasPermi="['anemometerTowerManage:anemometerTowerList:see']" link type="warning" icon="View" @click="handleView(data)"
            >查看</el-button
          >

          <el-button v-hasPermi="['anemometerTowerManage:anemometerTowerList:remove']" link type="danger" icon="Delete" @click="handleDelete(data)"
            >删除
          </el-button>
        </template>
      </myTable>

使用  js部分

const tableContent = reactive<any>({
  loading: true,
  column: [
    {
      label: '服务器地址',
      prop: 'serverAddress'
      // width: '120'
    },
    {
      label: '服务器端口',
      prop: 'serverPort'
      // width: '320'
    },
    {
      label: '是否加密',
      prop: 'ssl',
      slotName: 'ssl'
      // width: '100'
    },
    {
      label: '用户名',
      prop: 'username'
      // width: '100'
    },
    {
      label: '密码',
      prop: 'passwd'
      // width: '100'
    },
    // {
    //   label: '创建时间',
    //   prop: 'createTime'
    //   // width: '100'
    // },
    {
      slotName: 'action',
      prop: 'action',
      slotHeader: true,
      headerDisabled: true,
      label: '操作',
      width: '370'
    }
  ],
  tableDeta: [],
  pageObj: {
    pageNum: 1,
    pageSize: 10,
    pageSizes: [10, 20, 30, 40, 50],
    total: 0
  }
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一路向北. 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值