iView Table组件二次封装

1. 使用形式: 表格组件 x-table 使用时尽量看一下源码再使用

复制代码
// 并不完善 有待继续开发
x-table(
  :loading='loading'  // Table加载
  :columns='columns'  // 表格配置数据
  :data='featchData'  // 接口返回数据
  :immediately='false'// 是否立即执行 默认为true
  :pageSizes='[20]'   // 动态修改 pageSizes 默认为 [10, 20, 50, 100]
  @search='onFeatchData' // 查询数据事件
)
  <!-- 此处为iview表格自定义模版行为 -->
  template(slot-scope="{ row, index }" slot="actions")
    Button(type="primary" size="small" style="margin-right: 5px" @click="show(index)") View
    Button(type="error" size="small" @click="remove(index)") Delete

2. 表格组件 - 配置文件 columns.js

复制代码
<!-- 配置文件 -->
|------ key   对应数据展示字段
|------ title 展示内容
|------ width 表格宽度
|------ isHideColumn 为在表格中隐藏该列展示
|------ query 查询表单配置
  |------ form: 'select' 表单类型
  |------ defaultValue: 0 默认值
  |------ clearable: false 是否显示清空所有 默认为true
  |------ options 选项配置
|------ children 子级数据

export default [
  {
    key: 'card_type',
    title: '卡类型',
    isHideColumn: true,
    query: {
      form: 'select',
      defaultValue: 0,
      clearable: false,
      options: [
        {
          label: '全部',
          value: 0
        },
        {
          label: '实体卡',
          value: 2
        },
        {
          label: '电子卡',
          value: 3
        },
      ]
    },
  },
  {
    key: 'query_date',
    title: '时间',
    isHideColumn: true,
    query: {
      form: 'date',
      defaultValue: new Date(),
      clearable: false,
    },
  },
  {
    key: 'window_date',
    title: '窗口期',
    isHideColumn: true,
    query: {
      form: 'select',
      defaultValue: 0,
      clearable: false,
      options: [
        {
          label: '0天',
          value: 0
        },
        {
          label: '3天',
          value: 3
        },
        {
          label: '7天',
          value: 7
        },
        {
          label: '15天',
          value: 15
        },
        {
          label: '30天',
          value: 30
        },
      ]
    },
  },
  {
    key: 'ad_id',
    title: '计划ID',
    width: 200,
    query: {
      form: 'input',
    }
  },
  {
    key: 'dt',
    title: '日期',
  },
  {
    key: 'sold_unused_cnt',
    title: '包含子元素',
    children: [
      {
        key: 'total_income',
        title: '总收入',
      },
      {
        key: 'card_income',
        title: '售卡收入',
      },
    ]
  },
  {
    key: 'actions',
    title: '操作',
    width: 160,
    <!-- 需定义slot类型 对应第12行解释 -->
    slot: 'actions'
  },
]

3. 源码

复制代码
<template lang="pug">
.x-table
  //- 表单组件
  .form-box.main(v-if='dynamicQueryList.length > 0')
    //- 动态渲染各表单组件
    .query-box
      .query(v-for='i in dynamicQueryList' :key='i.key')
        //- Title
        .title {{ i.title }}:
        //- 日期时间组件
        DatePicker.form-item(
          v-if='i.query.form === "date"'
          v-model='form[i.key]'
          :class="i.query.type || 'date'"
          :type="i.query.type || 'date'"
          :format='i.query.format || "yyyy-MM-dd"'
          :placeholder='`请选择${i.placeholder || i.title}`'
          :clearable='i.query.clearable !== undefined ? i.query.clearable : true'
        )
        //- 下拉选择组件
        Select.form-item(
          v-else-if='i.query.form === "select"'
          v-model='form[i.key]'
          :placeholder='`请选择${i.placeholder || i.title}`'
          :clearable='i.query.clearable !== undefined ? i.query.clearable : true'
          @clear='form[i.key] = null'
          :filterable='i.query.filterable'
        )
          Option(
            v-for='item in i.query.options'
            :key='item.value'
            :label='item.label'
            :value='item.value'
          )
        //- 输入框组件
        Input.form-item(
          v-else
          v-model='form[i.key]'
          :placeholder='`请输入${i.placeholder || i.title}`'
          :clearable='i.query.clearable !== undefined ? i.query.clearable : true'
        )
    //- 操作组件
    .actions-box
      .action_btn
        Button(@click='handleSearch' type='primary') 查询
        Button(@click='handleReset') 重置
      //- 其他操作插槽
      slot(name='action' :form='form')
  //- 表格分页组件
  .table-box.main
    //- 头部slot
    slot(name='header')
    //- 表格组件
    Table(border :loading='loading' :columns='columnsComputed' :data='data.list || []')
      template(v-for='column in columnsSlotComputed' :slot='column.slot' slot-scope='params')
        slot(:name='column.slot' v-bind='params')
    //- 分页组件
    Page.pagination(
      v-if='data.total'
      show-total
      show-elevator
      show-sizer
      :total='data.total'
      :current='option.page'
      :page-size='option.pageSize'
      :page-size-opts='option.pageSizes'
      @on-change='handlePageChange'
      @on-page-size-change='handlePageSizeChange'
    )
    //- 底部slot
    slot(name='footer')
</template>

<script>
export default {
  name: 'x-table',
  props: {
    loading: { // Table加载
      type: Boolean,
      default: false
    },
    columns: Array, // 配置表格数据
    data: {
      type: Object,
      default: () => {
        return {
          list: [], // 数据列表
          total: 0 // 数据总量
        }
      }
    }, // 展示数据
    immediately: { // 是否立即执行
      type: Boolean,
      default: true
    },
    pageSizes: { // pageSizes 动态配置
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      // 检索表单绑定
      form: {},
      // 检索表单列表数据
      dynamicQueryList: [],
      option: {
        page: 1, // 当前展示页码
        pageSize: 20, // 每页展示数量
        pageSizes: [10, 20, 50, 100] // 每页显示个数选择器的选项设置
      }
    }
  },
  created () {
    // 设置检索数据
    this.setQuery()
    // 修改PageSizes配置
    if (this.pageSizes.length) {
      this.option.pageSizes = this.pageSizes
      this.option.pageSize = this.pageSizes[0]
    }
  },
  computed: {
    // 计算隐藏列展示项
    columnsComputed () {
      return this.columns.filter(i => !i.isHideColumn)
    },
    // 计算存在slot展示项
    columnsSlotComputed () {
      return this.columns.filter(i => !!i.slot)
    }
  },
  methods: {
    // 设置检索数据
    setQuery () {
      // 表单映射
      this.columns.forEach(column => {
        if (column.query) {
          this.dynamicQueryList.push(column) // 保存表单查询元素配置
          const defaultValue = column.query.defaultValue === undefined ? null : column.query.defaultValue // 获取初始值
          this.$set(this.form, column.key, defaultValue) // 动态设置query
        }
      })
      // 立即执行获取数据
      this.immediately && this.handleSearch()
    },
    // 重置数据
    handleReset () {
      this.dynamicQueryList.forEach(item => {
        this.form[item.key] = item.query.defaultValue === undefined ? null : item.query.defaultValue
      })
      this.handleSearch()
    },
    // 查询数据
    handleSearch () {
      const { page, pageSize } = this.option
      // 查询参数以及分页参数
      const query = {
        form: this.form,
        option: {
          page,
          pageSize
        }
      }
      this.$emit('search', query)
    },
    // 页码改变的回调,返回改变后的页码
    handlePageChange (page) {
      this.option.page = page
      this.handleSearch()
    },
    // 切换每页条数时的回调,返回切换后的每页条数
    handlePageSizeChange (pageSize) {
      this.option.pageSize = pageSize
      this.handleSearch()
    }
  }
}
</script>

<style scoped lang="less">
.x-table {
  .form-box {
    margin-bottom: 20px;
  }
  .query-box {
    display: flex;
    align-items: center;
    flex-flow: row wrap;
    .query {
      display: flex;
      align-items: center;
      margin: 0 20px 14px 0;
      .form-item {
        width: 180px;
        margin-left: 10px;
      }
      .daterange {
        width: 200px;
      }
      .datetimerange {
        width: 320px;
      }
    }
  }
  .actions-box {
    button {
      margin-right: 10px;
    }
  }

  .pagination {
    margin-top: 14px;
  }
}
</style>

最后编辑于:2025-06-15 10:17:20
© 著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务

相关推荐
计算机毕业设计小帅7 分钟前
【2026计算机毕业设计】基于Springboot的校园电动车短租平台
spring boot·后端·课程设计
superlls1 小时前
(Spring)Spring Boot 中 @Valid 与全局异常处理器的联系详解
java·spring boot·后端
勇敢di牛牛1 小时前
vue3 + mars3D 三分钟画一个地球
前端·vue.js
摇滚侠1 小时前
Spring Boot 3零基础教程,WEB 开发 整合 Thymeleaf 笔记36
java·spring boot·笔记
optimistic_chen2 小时前
【Java EE进阶 --- SpringBoot】Mybatis - plus 操作数据库
数据库·spring boot·笔记·java-ee·mybatis·mybatis-plus
来旺3 小时前
互联网大厂Java面试全解析及三轮问答专项
java·数据库·spring boot·安全·缓存·微服务·面试
摇滚侠3 小时前
Spring Boot 3零基础教程,yml文件中配置和类的属性绑定,笔记15
spring boot·redis·笔记
thginWalker3 小时前
使用Spring Boot构建消息通信层
spring boot
lang201509283 小时前
Spring Boot 外部化配置最佳实践指南
java·spring boot
我是日安3 小时前
从零到一打造 Vue3 响应式系统 Day 27 - toRef、toRefs、ProxyRef、unref
前端·javascript·vue.js