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>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容