引言:筆者爲前端小白,本文章是筆者初涉前端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完成了,用起來很方便,此處就不贅述了。