当前位置:   article > 正文

基于Vue.js框架和Element UI库编写的表格组件模板_vue表格

vue表格

基于Vue.js框架和Element UI库编写的表格组件模板。它包含了一系列的自定义选项和事件处理,使得表格可以根据不同的需求进行灵活的展示和操作。下面是对代码的详细解释:

模板部分(Template)

  1. el-table:这是Element UI中的表格组件,用于展示数据。
  2. v-loading:当数据正在加载时,显示加载动画。
  3. :data:绑定表格的数据源。
  4. :height:设置表格的高度。
  5. @selection-change:当选择行发生变化时触发的事件。
  6. :row-class-name:为表格行指定一个类名,可以用来设置行的样式。
  7. :header-cell-style:为表头单元格指定样式。
  8. stripe:是否为斑马纹 table。
  9. v-for:循环渲染列,根据column数组中的配置来创建el-table-column组件。

脚本部分(Script)

  1. filters:定义了一些Vue过滤器,用于对数据进行格式化处理。
  2. props:定义了组件的属性,包括表头样式、是否显示多选框、表格高度、加载状态、选择变化事件处理函数、列配置、行样式函数和表格数据。
  3. methods:定义了一些方法,用于格式化数据类型和数据格式。

样式部分(Style)

  1. scoped:表示样式的作用域限定在当前组件内。
  2. white-space: pre-wrap;:设置span标签的空白符处理方式,保持空白符的可见性。
  3. .el-table .warning-row.el-table .success-row:定义了表格中警告和成功状态行的背景色。
  4. .app-container /deep/:使用深度选择器来覆盖Element UI组件的默认样式,设置表格和单元格的背景色为透明。

整体来看,这个表格组件非常灵活,可以通过传入不同的column配置来渲染不同类型的列,如带有选择框、按钮、进度条、标签等。同时,它还支持自定义行样式和表头样式,以及通过事件处理函数来进行交互。

<template>
    <el-table
        ref="multipleTable"
        v-loading="tableLoading"
        :data="tableData"
        element-loading-text="拼命加载中"
        :height="height"
        element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(20, 60, 133, 0.8)"
        tooltip-effect="dark"
        style="width: 100%; "
        border
        :row-class-name="rowClassName"
        :header-cell-style="headerStyle"
        stripe
        @selection-change="handleSelectionChange"
      >
        <template v-if="isSelection">
          <el-table-column type="selection" width="55" />
        </template>
  
        <!-- 这里对数据进行处理  key不能加在template上,只能加在el-table-column上-->
        <template v-for="(item,index) in column">
          <el-table-column
              :key="index"
              :label="item.label"
              :type="item.type"
              :width="item.width"
              :fixed="item.fixed"
              :sortable="item.sortable?true:false"
              :filters="item.filters"
              :column-key="item.columnKey"
              :filtered-value="item.filteredValue"
              :filter-multiple="item.filterMultiple"
              :min-width="item.minWidth"
              align="center"
            >
             <!-- <div class="123" v-if="item.type == ''"> -->
          <template v-if="item.hasOwnProperty('colunmTemplate')" :slot="item.colunmTemplate" slot-scope="scope">
            <slot v-if="item.theadSlot" :name="item.theadSlot" :row="scope.row" :index="index" />
          </template >
  
          <template slot-scope="scope">
             <!-- 插槽 -->
             <div v-if="item.dataType == 'slot'">
                <slot v-if="item.slot" :name="item.slot" :row="scope.row" :index="scope.$index" />
            </div>
  
            <!-- 进度条 -->
            <div v-else-if="item.dataType == 'progress'">
              <el-progress :percentage="Number(scope.row[item.prop])" />
            </div>
  
             <!-- tag -->
            <div v-else-if="item.dataType == 'tag'">
                  <el-tag v-if="typeof dataTypeFn(scope.row[item.prop],item.formatData) == 'string'" :title="scope.row[item.prop] | formatters(item.formatData)" :type="formatType(scope.row[item.prop],item.formatType)">
                    {{ scope.row[item.prop] | formatters(item.formatData) }}
                  </el-tag>
  
                  <el-tag v-for="(tag,index) in dataTypeFn(scope.row[item.prop],item.formatData)" v-else-if="typeof dataTypeFn(scope.row[item.prop],item.formatData) == 'object'" :key="index" :title="scope.row[item.prop] | formatters(item.formatData)" :type="formatType(tag,item.formatType)">
                    {{ item.tagGroup ? tag[item.tagGroup.label]?tag[item.tagGroup.label]:tag : tag }}
                  </el-tag>
  
                  <el-tag v-else :title="scope.row[item.prop] | formatters(item.formatData)" :type="formatType(scope.row[item.prop],item.formatType)">
                    {{ scope.row[item.prop] | formatters(item.formatData) }}
                  </el-tag>
            </div>
  
             <!-- 按钮 -->
             <div v-else-if="item.dataType == 'option'">
                  <el-button
                    v-for="(o, key) in item.operation"
                    v-show="o.showHide?o.showHide(scope.row):true"
                    :key="key"
                    :icon="o.icon | iconFn(scope.row)"
                    :disabled="o.disabled?o.disabled(scope.row):false"
                    :plain="o.plain"
                    :type="o.type | typeFn(scope.row)"
                    :size="o.size"
                    @click="o.clickFun(scope.row,scope.$index)"
                  >
                    {{ o.name }}
                  </el-button>
            </div>
             <!-- 默认纯展示数据 -->
            <div v-else>
              <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span>
              <span v-else>{{ scope.row[item.prop] | formatters(item.formatData) }}</span>
            </div>
          </template>
          </el-table-column>
        </template>
      </el-table>
  </template>
  
  <script>
  export default {
    filters:{
      iconFn(val, row) {
        if (typeof (val) === 'function') {
          return val(row)
        } else return val
      },
      typeFn(val, row) {
        console.log(val,row,'11111111');
        if (typeof (val) === 'function') {
          return val(row)
        } else return val
      },
      describeConts(val, describeCont) {
        if (typeof (describeCont) === 'function') {
          return describeCont(val)
        } else return val
      },
      formatters(val, format) {
        if (typeof (format) === 'function') {
          return format(val)
        } else return val
      }
    },
    props:{
      headerStyle:{//默认的头部背景色
        type: Object,
        default: () => {
          return {
            background: '#0e3372',
            color: '#cccccc'
          }
        }
      },
      isSelection: {//是否是多选框
        type: Boolean,
        default: false
      },
      height: {
        type: Number,
        default: null
      },
      tableLoading: {//是否显示加载动画
        type: Boolean,
        default: false
      },
      handleSelectionChange: {
        type: Function,
        default: () => {
          return () => {}
        }
      },
      headerCellStyle: {
        type: Object,
        default: () => {
          return {}
        }
      },
      column: {
        type: Array,
        default() {
          return [
          ]
        }
      },
      rowClassName: {
        type: Function,
        default: () => {
  
        }
      },
      tableData: {
        type: Array,
        default() {
          return []
        }
      }
    },
    methods: {
      formatType(val, format) {
        if (typeof (format) === 'function') {
          return format(val)
        } else return ''
      },
      dataTypeFn(val, format) {
        if (typeof (format) === 'function') {
          return format(val)
        } else return val
      }
    }
  }
  </script>
  
  <style scoped>
  span{
    white-space: pre-wrap;
  }
    .el-table .warning-row {
      background: oldlace;
    }
    .el-table .success-row {
      background: #f0f9eb;
    }
  
  .app-container /deep/  .el-table, .el-table__expanded-cell {
    background-color: transparent;
  }
  .app-container /deep/ .el-table tr {
    background-color: transparent!important;
  }
  .app-container /deep/  .el-table--enable-row-transition .el-table__body td, .el-table .cell{
    background-color: transparent;
  }
  </style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210

要使用这个表格组件,你需要遵循以下步骤:

1. 引入组件

首先,你需要在你的Vue项目中引入这个表格组件。通常,这个组件会被保存在一个单独的文件中,比如CustomTable.vue。在你的页面组件或者应用入口文件中,导入并注册这个表格组件:

import CustomTable from './CustomTable.vue';

export default {
  components: {
    CustomTable
  },
  // ...
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2. 定义列配置和数据

在你的页面组件的data函数中,定义columntableData数组,这些数组将用来控制表格的列显示和数据填充。

data() {
  return {
    column: [
      // 定义列的配置,例如:
      {
        label: '姓名',
        prop: 'name',
        dataType: 'text', // 数据类型,可以是 'text', 'slot', 'progress', 'tag', 'option' 等
        minWidth: 80
      },
      // ...更多列配置
    ],
    tableData: [
      // 表格的数据,例如:
      { name: '张三', age: 25, gender: '男' },
      // ...更多数据项
    ],
    // ...其他属性
  };
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

3. 在模板中使用组件

在你的页面模板中,插入CustomTable组件,并绑定必要的属性和事件。

<template>
  <div>
    <!-- 使用自定义表格组件 -->
    <CustomTable
      :tableData="tableData"
      :column="column"
      :isSelection="true" <!-- 如果需要选择框 -->
      :height="500" <!-- 表格高度 -->
      @selection-change="handleSelectionChange" <!-- 选择变化事件 -->
      :headerStyle="{ background: '#f5f5f5', color: '#333' }" <!-- 表头样式 -->
      :rowClassName="rowClass" <!-- 行样式 -->
    />
  </div>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4. 处理事件和插槽

如果你的列配置中使用了插槽(slot),你需要在父组件中定义相应的插槽内容。对于事件,如选择框变化事件,你需要在父组件的methods中定义处理函数。

<template>
  <div>
    <!-- 插槽示例 -->
    <template v-slot:default="slotProps">
      <!-- 自定义内容 -->
    </template>
    <!-- 组件使用 -->
    <CustomTable
      :tableData="tableData"
      :column="column"
      // ...
    />
  </div>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
methods: {
  handleSelectionChange(selection) {
    // 处理选择框变化事件
    console.log(selection);
  },
  rowClass({ row, rowIndex }) {
    // 根据行数据或索引返回样式
    if (rowIndex % 2 === 0) {
      return 'warning-row';
    } else {
      return 'success-row';
    }
  }
  // ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5. 自定义方法和过滤器

如果你需要自定义数据处理方法或过滤器,可以在父组件中定义它们,并在filters中注册。这些方法和过滤器将在表格组件中被用来格式化数据。

filters: {
  customFormatter(value) {
    // 自定义格式化逻辑
    return value.toString().toUpperCase();
  }
},
methods: {
  customMethod(row) {
    // 自定义方法逻辑
    // 可以基于行数据进行操作
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在表格组件的column配置中,你可以通过dataTypeFnformatType等属性来引用这些自定义的方法和过滤器。

6. 完整示例

下面是一个完整的父组件使用表格组件的示例:

<template>
  <div>
    <CustomTable
      :tableData="tableData"
      :column="column"
      :isSelection="true"
      :height="500"
      @selection-change="handleSelectionChange"
      :headerStyle="{ background: '#f5f5f5', color: '#333' }"
      :rowClassName="rowClass"
    />
  </div>
</template>

<script>
import CustomTable from './CustomTable.vue';

export default {
  components: {
    CustomTable
  },
  data() {
    return {
      tableData: [
        { name: '张三', age: 25, gender: '男' },
        // ...更多数据项
      ],
      column: [
        {
          label: '姓名',
          prop: 'name',
          dataType: 'text',
          minWidth: 80
        },
        {
          label: '年龄',
          prop: 'age',
          dataType: 'progress', // 假设年龄用进度条表示
          minWidth: 100
        },
        // ...更多列配置
      ],
      // ...其他属性
    };
  },
  methods: {
    handleSelectionChange(selection) {
      console.log(selection);
    },
    rowClass({ row, rowIndex }) {
      if (rowIndex % 2 === 0) {
        return 'warning-row';
      } else {
        return 'success-row';
      }
    }
  },
  filters: {
    customFormatter(value) {
      return value.toString().toUpperCase();
    }
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

通过以上步骤,你可以在你的Vue应用中使用这个自定义的表格组件,并根据需要进行灵活的配置和扩展。

在表格配置中添加处理事件的按钮

你需要在column数组中定义一个具有dataType'option'的对象,这个对象将包含一个operation数组,用来定义按钮的配置。每个按钮配置对象应包含name(按钮显示的文本)、icon(按钮图标)、type(按钮类型)、size(按钮大小)、plain(是否为朴素按钮)、disabled(是否禁用按钮)以及clickFun(点击按钮时触发的事件处理函数)。

以下是一个具体的配置示例:

data() {
  return {
    column: [
      // ...其他列配置
      {
        label: '操作',
        dataType: 'option', // 指定该列为操作列,将渲染按钮
        minWidth: 120, // 列宽
        operation: [
          {
            name: '编辑', // 按钮显示的文本
            icon: 'el-icon-edit', // 按钮图标
            type: 'primary', // 按钮类型
            size: 'mini', // 按钮大小
            clickFun: this.editRow // 点击按钮时触发的事件处理函数
          },
          {
            name: '删除',
            icon: 'el-icon-delete',
            type: 'danger',
            size: 'mini',
            plain: true, // 朴素按钮
            disabled: false, // 是否禁用按钮
            clickFun: this.deleteRow // 点击按钮时触发的事件处理函数
          }
        ]
      }
    ],
    tableData: [
      // 表格的数据
    ],
    // ...其他数据和方法
  };
},
methods: {
  editRow(row, index) {
    // 编辑操作的逻辑
    console.log('编辑操作', row, index);
  },
  deleteRow(row, index) {
    // 删除操作的逻辑
    console.log('删除操作', row, index);
    // 通常这里会有一个确认操作的弹窗,用户确认后才执行删除逻辑
  }
  // ...其他方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

CustomTable组件的模板中,你需要确保el-table-columndataType设置为'option',并且在该列的模板中渲染按钮。这通常是通过v-for指令在operation数组上循环来实现的:

<template slot-scope="scope">
  <div v-if="item.dataType === 'option'">
    <el-button
      v-for="(o, key) in item.operation"
      :key="key"
      :icon="o.icon"
      :type="o.type"
      :size="o.size"
      :plain="o.plain"
      :disabled="o.disabled ? o.disabled(scope.row) : false"
      @click="o.clickFun(scope.row, scope.$index)"
    >
      {{ o.name }}
    </el-button>
  </div>
  <!-- ...其他数据类型的渲染 -->
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

请注意,clickFun属性是一个函数,它接受当前行的数据和行索引作为参数。在父组件中,你需要定义相应的方法来处理按钮点击事件,并确保这些方法能够访问到正确的数据和索引。

通过这种方式,你可以在表格中添加具有事件处理功能的按钮,并根据需要自定义按钮的样式和行为。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/965281
推荐阅读
相关标签
  

闽ICP备14008679号