vue + antd项目中关于Table的那些事儿之排序筛查

引言:笔者为前端小白,本文章是笔者初涉前端vue+antd的第一和第二个项目中代码分享,仅供初学者参考。

概要:利用antd组件库的table组件完成数据按格式渲染,分页/翻页,排序,查询,筛选功能;

注意:本demo前端分页;

步入正题:

1、引入antd组件库

$ npm i --save ant-design-vue

2、按需引入table组件

import Vue from 'vue';
import { Table } from 'ant-design-vue';

Vue.use(Table)

3、调用组件完成简单的数据渲染和分页

<!-- dom结构 -->
      <a-table
        row-key="id"
        :columns="columns"
        :loading="loading"
        :data-source="list"
        :pagination="pagination"
        @change="handlePageChange"
      >
        <template slot="operation" slot-scope="id, record">
          <a
            @click="() => handleClickEdit(record.id)"
          >
            编辑
          </a>
          <a
            @click="() => handleClickDelete(record.id)"
          >
            删除
          </a>
          <a @click="() => handleClickDetail(record.id)">
            详情
          </a>
        </template>
      </a-table>
<script>
const columns = [
  { title: "货品名称", dataIndex: "goods" },
  { title: "进货数量", dataIndex: "quantity" },
  { title: "单价", dataIndex: "price" },
  { title: "剩余数量", dataIndex: "rest" },
  { title: "创建者", dataIndex: "creater" },
  { title: "创建日期", dataIndex: "createTime" },
  {
  {
    title: "操作",
    dataIndex: "operation",
    className: "column-operate",
    scopedSlots: { customRender: "operation" }
  }
];

export default {
  name: "SmsList",
  data() {
    return {
      list: [],
      columns,
      loading: true,
      pagination: {
        current: 1, // 当前页数 v-model
        defaultCurrent: 1, // 默认的当前页数
        defaultPageSize: 10, // 每页显示几条数据
        pageSize: 10,
        showQuickJumper: true, // 是否显示直通车
        showSizeChanger: true, // 显示下拉选项(每页几条)
        pageSizeOptions: ["10", "20", "50"]
      },
      currentPage: 1,
      currentPageSize: 10
    };
  },
 methods: {
    // 点击换页
    handlePageChange(pagination) {
      this.currentPage = pagination.current;
      this.currentPageSize = pagination.pageSize;
      this.getList(); //获取数据
      const pager = { ...this.pagination };
      pager.current = pagination.current;
      pager.pageSize = pagination.pageSize;
      this.pagination = pager;
    },
 },
}
</script>

4、增加排序(仅需在columns变量定义中增加排序规则)

const columns = [
  { title: "货品名称", dataIndex: "goods" },
  { title: "进货数量", dataIndex: "quantity", sorter: (a, b) => a.quantity - b.quantity, } },
  { title: "单价", dataIndex: "price" },
  { title: "剩余数量", dataIndex: "rest" },
  { title: "创建者", dataIndex: "creater" },
  { title: "创建日期", dataIndex: "createTime" },
  {
  {
    title: "操作",
    dataIndex: "operation",
    className: "column-operate",
    scopedSlots: { customRender: "operation" }
  }
];

排序方法:升序(假设排序列的detaIndex为key)

1)按内容有无/数字大小排序:sorter: (a, b) => a.key - b.key;

2)按内容长度排序:sorter: (a, b) => a.key.length - b.key.length;

3)按字母/姓名排序:sorter: (a, b) => a.key.localeCompare(b.key),

5、增加筛选和查询功能(关于筛选:官方文档的方法是指定几项作为筛选项,此处举例采用的是根据内容自动生成筛选项的方法)

            <a-table
                row-key="id"
                :columns="columns"
                :data-source="list"
                :pagination="pagination"
                @change="handleChange"
              >
                <div
                  slot="filterDropdown"
                  slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }"
                  style="padding: 8px"
                >
                  <a-input
                    :placeholder="`按${column.title}筛选`"
                    :value="selectedKeys[0]"
                    style="width: 188px; margin-bottom: 8px; display: block;"
                    @change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
                    @pressEnter="() => handleSearch(selectedKeys, confirm, column.dataIndex)"
                  />
                  <a-button
                    type="primary"
                    size="small"
                    style="width: 80px; margin-right: 20px"
                    @click="() => handleSearch(selectedKeys, confirm, column.dataIndex)"
                  >
                    筛选
                  </a-button>
                  <a-button
                    size="small"
                    style="width: 80px"
                    @click="() => handleReset(clearFilters)"
                  >
                    重置
                  </a-button>
                </div>
                <a-icon
                  slot="filterIcon"
                  slot-scope="filtered"
                  type="search"
                  :style="{ color: filtered ? '#108ee9' : undefined }"
                />
            </a-table>
<script>
 computed: {
columns() {
 let { typeFilter } = this
      typeFilter = typeFilter || {}
      const columns = [{
       title: '货品名称',
          dataIndex: 'goods',
          scopedSlots: { filterDropdown: 'filterDropdown', filterIcon: 'filterIcon', customRender: 'goods' },
          onFilter: (value, record) => record.goods.toString().toLowerCase().includes(value.toLowerCase()),
        }, {
          title: '所属品种',
          dataIndex: 'type',
          filters: typeFilter,
          onFilter: (value, record) => { return record.type && record.type.indexOf(value) === 0 } },
      { title: "进货数量", dataIndex: "quantity", sorter: (a, b) => a.quantity - b.quantity, } },
      { title: "单价", dataIndex: "price" },
      { title: "剩余数量", dataIndex: "rest" },
      { title: "创建者", dataIndex: "creater" },
      { title: "创建日期", dataIndex: "createTime" 
    }]
    return columns
}
}
created() {
    // 获取menu数据并渲染menu
    this.getData()
},
methods:{
// 获取列表数据
    async getData() {
      try {
        const result = await this.$api.okr.getlist({/* 参数 */})
        const temArr = []
        if(result) {
            result.forEach(i => {
              // 收集品种名称的集合
            if (i.type) {
                temArr.push(i.type)
            }
          })
          this.typeFilter = []
          const newArr = [...new Set(temArr)] // ES6的新语法 数组去重
          newArr.forEach(i => {
            this.typeFilter.push(
              { text: i, value: i }
            )
          })

          this.$set(this, 'list', result)
          const pagination = { ...this.paginationDP }
          this.pagination = pagination
        }
      } catch (error) {
        const msg = error.errorMessage || error.message || '网络错误'
        console.log(msg)
      
    },
    // 点击换页
    handleChange(pagination) {
      const pager = { ...this.pagination }
      pager.current = pagination.current
      pager.pageSize = pagination.pageSize
      this.pagination = pager
    },
}

</script>

效果图如下:

        

 

此外,antd的Table组件比较常用的还有固定列,这里需要注意的就是:scroll="{ x: 值}",这个x对应的值不能超过滚动列宽度的和,笔者在用到的时候反复调整过,最后发现,太多的列容易出现遮挡问题,建议不要超过连续两列固定列,且如果表格不定宽度,最好给固定列指定宽度。

另外笔者还遇到合并行的需求,感觉用此组件过于麻烦,干脆自行table嵌套+v-for完成了,用起来很方便,此处就不赘述了。


版权声明:本文为hellowwj0715原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。