iView Table组件二次封装

2021-01-19  本文已影响0人  光明大兄弟

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>

上一篇 下一篇

猜你喜欢

热点阅读