vue3封装element-plus的el-table

封装的el-table公共组件table.vue
注意深拷贝用的lodash方法,以及使用了jsx渲染列的标签和事件


<template>
  <div class="page-view flex-center">
    <el-table v-loading="tableData.tableLoading" ref="multipleTableRef" class="jg-table" :data="tableData.data"
      style="width: 100%;" @selection-change="handleSelectionChange" @row-click="rowClick" @sort-change="sortChange">

      <template v-for="(item, index) in  tableData.columnsData " :key="index">

        <!-- 多选 -->
        <el-table-column v-if="item.type === 'selection'" :type="item.type" :width="item.width" />
        <!-- 单选 -->
        <el-table-column v-else-if="item.type === 'radio'" :width="item.width" class-name="no-radio-label">
          <template #default="{ row, $index }">
            <el-radio @change="changeRadio" v-model="radioIndex" :label="row"></el-radio>
          </template>
        </el-table-column>
        <!-- 渲染formatter -->
        <el-table-column v-else :property="item.field" :label="item.title" :width="item.width" :min-width="item.minWidth"
          :max-idth="item.maxWidth" :showOverflowTooltip="item.showOverflowTooltip" :sortable="item.sortable"
          :formatter="item.formatter" />
      </template>

    </el-table>
  </div>
</template>

<script lang="jsx">
import {
    
     ref, defineComponent, getCurrentInstance, h } from 'vue' // 按需引入ref函数

import {
    
     Delete, Edit, Download, QuestionFilled, EditPen, Tickets } from '@element-plus/icons-vue'


export default defineComponent({
    
    
  name: 'JgTable',
  props: {
    
    
    tableDataObj: {
    
     // 父组件传递的表格数据
      type: Object,
      default: () => {
    
    
        return {
    
    }
      }
    },
  },
  emits: ['update:editItem'],
  setup(props, {
    
     emit }) {
    
    
    const {
    
     proxy } = getCurrentInstance()

    let tableData = ref({
    
    })
    let radioIndex = ref(null)

    watch([() => props.tableDataObj, () => props.rulesData], ([tableDataObj, rulesData]) => {
    
    
      console.log('监听');
      tableData.value = proxy.$_.cloneDeep(tableDataObj) // 注意深拷贝的方法 我用的lodash的
      // rules.value = proxy.$_.cloneDeep(rulesData)
    }, {
    
     deep: true, immediate: true })

    // 编辑操作
    function editItem(row, type) {
    
    
      console.log(row, type,);

      // 子传父
      emit('update:editItem', {
    
     row: row, type: type });
    }

    const myDiv = () => h('div', null, 'Hello, 1')

    // 多选
    const handleSelectionChange = (val) => {
    
    
      console.log(val);
      // 子传父
      emit('update:handleSelectionChange', val);
    }
    // 单选
    const changeRadio = (val) => {
    
    
      // console.log('单选', val, radioIndex.value.aa);
      emit('update:changeRadio', val);
    }

    // 表格点击事件
    const rowClick = (val) => {
    
    
      // console.log(val);
    }

    // 排序
    const sortChange = (val) => {
    
    
      // console.log(val);
      emit('update:sortChange', val);
    }




    // 将变量和函数返回,以便在模版中使用
    return {
    
    
      myDiv,
      radioIndex,

      tableData,

      editItem,
      handleSelectionChange,
      changeRadio,
      rowClick,
      sortChange,

      EditPen,
      Tickets,

    }
  }
})
</script>
<style lang="scss" scoped>
// 去除单选框的内容
:deep(.no-radio-label) {
    
    
  .el-radio__label {
    
    
    display: none;
  }
}
</style>

父组件far.vue使用封装的表格

<template>

    <JgTable :tableDataObj="tableData" @update:editItem="updateEditItem" @update:handleSelectionChange="updateHandleSelectionChange" @update:changeRadio="updateChangeRadio" @update:sortChange="updateSortChange"></JgTable>

</template>


对应表格数据
    let tableData = ref({
    
    
      tableLoading: false,
      // title:名称 field:key type:单选复选框 width minWidth maxWidth showOverflowTooltip formatter:格式化内容
      columnsData: [
        {
    
     title: '多选', type: 'selection', width: 55 },
        // {
    
     title: '单选', type: 'radio', width: 55 },
        {
    
     title: '缺陷名称', field: 'aa', formType: 'input', width: 120 },
        {
    
     title: '缺陷描述', field: 'bb', formType: 'input', showOverflowTooltip: true },
        {
    
     title: '缺陷发布时间', field: 'cc', formType: 'date', dateType: 'YYYY-MM-DD', width: 140 },
        // {
    
     title: '缺陷发布时间',  field: 'cc', formType: 'datetime', dateType: 'YYYY-MM-DD HH:mm:ss' },
        {
    
    
          title: '设备类型', field: 'dd', formType: 'select', width: 120, selectList: [
            {
    
     name: '横向隔离', value: 0 },
            {
    
     name: '纵向加密', value: 1 },
            {
    
     name: '防火墙', value: 2 },
            {
    
     name: '监测装置', value: 3 },
            {
    
     name: '运维网关', value: 4 },
            {
    
     name: '其他', value: 5 },
          ],

          formatter: (row) => {
    
    
            const val = [
              {
    
     name: '横向隔离', value: 0 },
              {
    
     name: '纵向加密', value: 1 },
              {
    
     name: '防火墙', value: 2 },
              {
    
     name: '监测装置', value: 3 },
              {
    
     name: '运维网关', value: 4 },
              {
    
     name: '其他', value: 5 },
            ].find(item => item.value === row.dd)?.name || ''
            return <span>{
    
    val}</span>
          }
        },
        {
    
     title: '设备厂家', field: 'ee', formType: 'input' },
        {
    
     title: '设备版本', field: 'ff', formType: 'input', width: 160, showOverflowTooltip: true },
        {
    
     title: '缺陷设备数量', field: 'gg', formType: 'input', sortable: 'custom' },
        {
    
    
          title: '缺陷反馈状态', field: 'hh', formType: 'radio', minWidth: 100, selectList: [
            {
    
     name: '已反馈', value: 1 },
            {
    
     name: '未反馈', value: 0 },
          ],
          formatter: (row) => (
            row ? <el-tag style="border: none;" class="cursor" type={
    
    row.hh === 1 ? 'green' : 'warning'}>{
    
    row.hh === 1 ? '已反馈' : row.hh === 0 ? '未反馈' : ''}</el-tag> : ''
          )
        },
        {
    
    
          title: '缺陷处置进度', field: 'ii', formType: 'progress',
          formatter: (row) => (
            <el-progress class="table_progress" width="13" stroke-width="2" type="circle" percentage={
    
    row.ii} />
          )
        },
        // {
    
    
        //   title: '测试', field: 'ceshi',width: 200,
        //   formatter: (row, column) => {
    
    
        //     // console.log(112,row, column); // 直接{
    
    row}{
    
    column} 不会显示内容
        //     return  [<el-tag type={
    
    row.ceshi == "可发放" ? "success" : "danger"} onClick={
    
    () => editItem(row, 'view')}> {
    
    row.ceshi} </el-tag>, <span>{
    
    column.label}</span>]
        //   }
        // },
        {
    
    
          title: '操作', field: 'caozuo', width: 140,
          formatter: (row) => (
            [
              <el-button link type="primary" size="small" icon={
    
    Tickets} onClick={
    
    () => editItem(row, 'view')} > 查看</el-button >,
              <el-button link type="primary" size="small" icon={
    
    EditPen} onClick={
    
    () => editItem(row, 'edit')} > 编辑</el-button >
            ]
          )
        },

      ],
      data: Array.from({
    
     length: 7 }).map((ele, index) => {
    
    
        return {
    
    
          aa: '客户端不适配',
          bb: '客户端无法适配凝思 4.2.40',
          cc: '2023-7-20',
          dd: proxy.$_.random(0, 3),
          ee: '帕拉迪',
          ff: 'PLD Sys 61012100',
          gg: proxy.$_.random(0, 20),
          hh: proxy.$_.random(0, 1),
          ii: proxy.$_.random(0, 100),
          ceshi: 123,
        }
      })
    })

对应方法
    // 子组件调用父组件的测试事件
    const updateEditItem =(data)=>{
    
    
      console.log('子组件调用父组件的测试事件',data);
      editItem(data.row,data.type)
    }
    const updateHandleSelectionChange =(data)=>{
    
    
      if (data.length > 0) {
    
    
        feedbackFlag.value = false
      } else {
    
    
        feedbackFlag.value = true
      }
    }
    const updateChangeRadio =(data)=>{
    
    
      console.log(data);
      if (data) {
    
    
        feedbackFlag.value = false
      } else {
    
    
        feedbackFlag.value = true
      }
    }
    const updateSortChange =(data)=>{
    
    
      console.log(data);
    }

猜你喜欢

转载自blog.csdn.net/i_am_a_div/article/details/133241956