官方文檔: https://www.antdv.com/components/table-cn/
注意 #
在 Table 中,
dataSource
和columns
里的數據值都需要指定key
值。對於dataSource
默認將每列數據的key
屬性作為唯一的標識。如果你的數據沒有這個屬性,務必使用
rowKey
來指定數據列的主鍵。若沒有指定,控制台會出現缺少 key 的提示,表格組件也會出現各類奇怪的錯誤。
Column #
列描述數據對象,是 columns 中的一項,Column 使用相同的 API。
dataIndex 列數據在數據項中對應的 key,支持 a.b.c 的嵌套寫法
key Vue 需要的 key,如果已經設置了唯一的 dataIndex,可以忽略這個屬
也就是說column 如果指定了dataIndex 可以不用指定key
最基本的表格
<template>
<a-table :columns="columns" :data-source="data">
</a-table>
</template>
<script>
//表頭數據
//title 為表頭的標題 dataIndex為列數據在數據項中對應的 key
//
const columns = [
{
title : 'name',
dataIndex: 'name',
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
{
title: 'Action',
dataIndex: 'action',
},
];
//表格數據
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
action: '123465'
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
];
export default {
data() {
return {
data,
columns,
};
},
};
</script>
效果
給最后一列加上編輯和刪除按鈕
如果想在最后一列渲染html 直接在data數組中寫html代碼是沒用的,會直接解析成字符串,那么怎么辦呢?
官方使用的方式是:插槽
表格插槽的使用
1.在
例:
<!--插槽一定要在表格組件標簽中-->
<!--定義插槽渲染-->
<!--
slot="action" 表示是在columns(某列)中的表頭值為action中插入標簽,往這個位置插入插槽span中間的內容
slot-scope="text, record, index"
text 表示當前行當前列的值
record 表示當前行的數據
index 表格索引
-->
<span slot="action" slot-scope="text, record, index">
<a-button type="primary" @click="edit(text, record, index)">編輯</a-button>
<a-button type="danger">刪除</a-button>
</span>
2.表頭數據列(columns)中,使用插槽
例:
{
title: 'Action',
dataIndex: 'action',
//使用插槽
scopedSlots: { customRender: 'action' },
},
3.定義點擊事件
例:
export default {
data() {
return {
data,
columns,
};
},
methods:{
edit(text, record, index){
console.log(text)
console.log(record)
console.log(index)
}
}
};
效果
完整代碼
<template>
<a-table :columns="columns" :data-source="data">
<!--插槽一定要在表格組件標簽中-->
<!--定義插槽渲染-->
<!--
slot="action" 表示是在columns(某列)中的表頭值為action中插入標簽,往這個位置插入插槽span中間的內容
slot-scope="text, record, index"
text 表示當前行當前列的值
record 表示當前行的數據
index 表格索引
-->
<span slot="action" slot-scope="text, record, index">
<a-button type="primary" @click="edit(text, record, index)">編輯</a-button>
<a-button type="danger">刪除</a-button>
</span>
</a-table>
</template>
<script>
//表頭數據
//title 為表頭的標題 dataIndex為列數據在數據項中對應的 key
const columns = [
{
title : 'name',
dataIndex: 'name',
},
{
title: 'Age',
dataIndex: 'age',
},
{
title: 'Address',
dataIndex: 'address',
},
{
title: 'Action',
dataIndex: 'action',
//使用插槽
scopedSlots: { customRender: 'action' },
},
];
//表格數據
const data = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
action: '123465'
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
];
export default {
data() {
return {
data,
columns,
};
},
methods:{
edit(text, record, index){
console.log(text)
console.log(record)
console.log(index)
}
}
};
</script>
rowKey屬性 綁定每行的key
rowKey 表格行 key 的取值,可以是字符串或一個函數 string|Function(record):string 'key'
在最開始,就提到了表格的表頭和表格數據都必須有個唯一的key,不過不指定會怎么樣呢?會報錯,如
warning.js?2149:7 Warning: [antdv: Each record in table should have a unique
key
prop,or setrowKey
to an unique primary key.]
這時候你如果數據是靜態,直接加上key就可以,那如果數據是從后端獲取的並且后端沒有key這個屬性,而是其他屬性。怎么辦呢?這時候可以用rowKey屬性進行綁定
如:
<!--
:columns="columns" 表頭數據
:data-source="data" 表格數據
:rowKey="record => record.id" id為 Data 中的一個屬性
-->
<a-table :columns="columns" :data-source="data" :rowKey="record => record.id">
全部方式
rowKey 取值方式
帶冒號的表示綁定的是表達式
不帶的表示綁定的就是值
<a-table
:columns="columns"
:data-source="data"
size="middle"
:rowKey='record=>record.id'> <!--id為 data 中的一個屬性-->
</a-table>
<a-table
:columns="columns"
:data-source="data"
size="middle"
:rowKey="(record,index)=>{return index}"> <!--record 為每一條數據, index 索引-->
</a-table>
<a-table
:columns="columns"
:data-source="data"
size="middle"
rowKey="id"> <!--id為 data 中的一個屬性 !!! 這里的rowKey不需要冒號 -->
</a-table>
表格數據是否加載中
loading 頁面是否加載中 boolean|object false
例:
表格標簽中設置 :loading="loading" 屬性綁定
<a-table :columns="columns" :data-source="data" rowKey="id" :loading="loading">
設置默認值
data() {
return {
//為true表示 正在加載中
loading : true,
};
}
修改loading狀態
getAdminList() {
this.axios.get(process.env.VUE_APP_API_URL + this.urls.admin_list).then((data) => {
//修改loading 狀態
this.loading = false;
});
},
上面這個例子表示,表格初始為load狀態,獲取完后為load完畢
表格分頁
pagination 分頁器,參考配置項或 pagination文檔,設為 false 時不展示和進行分頁 object
事件
change 分頁、排序、篩選變化時觸發 Function(pagination, filters, sorter, { currentDataSource })
https://www.antdv.com/components/table-cn/#事件
https://www.antdv.com/components/pagination-cn/#API
注意:寫完需要重啟服務和清除緩存
例:
表格組件設置綁定pagination
<!--表格-->
<!--
:columns="columns" 表頭數據
:data-source="data" 表格數據
rowKey="id" id為 data 中的一個屬性
:loading="loading" 表格是否load
:pagination="pagination" 分頁參數
-->
<a-table :columns="columns" :data-source="data" rowKey="id" :loading="loading" :pagination="pagination" >
<span slot="status" slot-scope="text, record, index">
<div v-if="text == 1">
<a-button type="primary" @click="changeActive(text, record, index)">已啟用</a-button>
</div>
<div v-else>
<a-button type="danger" @click="changeActive(text, record, index)">已禁用</a-button>
</div>
</span>
<!--插槽一定要在表格組件標簽中-->
<!--定義插槽渲染-->
<!--
slot="action" 表示是在columns(某列)中的表頭值為action中插入標簽,往這個位置插入插槽span中間的內容
slot-scope="text, record, index"
text 表示當前行當前列的值
record 表示當前行的數據
index 表格索引
-->
<span slot="action" slot-scope="text, record, index">
<a-button type="primary" @click="edit(text, record, index)">編輯</a-button>
<a-button type="danger">刪除</a-button>
</span>
</a-table>
設置data()
里面的初始化參數
//表格數據
data : [],
/**
* 表頭數據
* title 為表頭的標題
* dataIndex為列數據在數據項中對應的 key
* scopedSlots 對應插槽
*/
columns : [
{
title: '登錄用戶名',
dataIndex: 'username',
},
{
title: '昵稱',
dataIndex: 'nickname',
},
{
title: '狀態',
dataIndex: 'status',
scopedSlots: {customRender: 'status'},
},
{
title: '操作',
dataIndex: 'action',
//使用插槽
scopedSlots: {customRender: 'action'},
},
],
//表格load標志
loading : true,
//表格分頁參數
pagination: {
pageNo: 1,
pageSize: 10, // 默認每頁顯示數量
showSizeChanger: true, // 顯示可改變每頁數量
pageSizeOptions: ['10', '20', '50', '100'], // 每頁數量選項
showTotal: total => `共 ${total} 條數據`, // 顯示總數
onShowSizeChange: (current, pageSize) => this.changePageSize(current, pageSize), // 改變每頁數量時更新顯示
onChange:(page,pageSize)=>this.changePage(page,pageSize),//點擊頁碼事件
total:0 //總條數
},
設置methed
觸發的相關方法
//獲取管理員列表
getAdminList(param) {
//初始化分頁參數
if(param === undefined || param === null){
param = {
current : 1,
pageSize : 10
}
}
//http://www.myadmin.com/api/system/admin?pageNow=1&pageSize=100
this.axios.get(process.env.VUE_APP_API_URL + this.urls.admin_list,{params: {
pageNow : param.current,
pageSize : param.pageSize,
}}).then((data) => {
//修改loading 狀態
this.loading = false;
//數據
this.data = data.data.data.data;
//分頁參數
/* this.pagination.current = data.data.data.pageNow;
this.pagination.pageSize = data.data.data.pageSize;
this.pagination.showTotal = data.data.data.lineCount;*/
this.pagination.total = data.data.data.lineCount;
console.log(this.pagination);
});
},
//點擊頁碼事件
changePage(page,pageSize) {
console.log(page, '當前頁.......');
console.log(pageSize, '每頁大小.......');
this.getAdminList({
current : page,
pageSize : pageSize
})
},
//每頁顯示數量改變的事件
changePageSize(current, pageSize){
console.log(current, '當前頁.......');
console.log(pageSize, '每頁大小.......');
this.getAdminList({
current : current,
pageSize : pageSize
})
},
鈎子函數初始化數據
//頁面渲染之前,$el創建之后 去加載
mounted() {
//獲取左側菜單
this.getAdminList();
},
后端接口tp5.1
//管理員列表
public function index(){
$data = input('');
//dump($data);
//默認
$pageNow = 1;//當前頁
$pageSize = 10;//一頁多少行
$lineCount = 0;//總記錄數
$pageCount = 0;//總頁數
if(!empty($data)){
if(isset($data['pageNow'])){
$pageNow = $data['pageNow'];
}
if(isset($data['pageSize'])){
$pageSize = $data['pageSize'];
}
}
$lineCount = AdminModel::count();
$pageCount = ceil($lineCount / $pageSize);
$data = AdminModel::order('id', 'desc')->limit(($pageNow-1) * $pageSize,$pageSize)->select();
return $this->returnJson(200, '管理員列表', [
'pageNow' => (int)$pageNow,
'pageSize' => (int)$pageSize,
'lineCount' => (int)$lineCount,
'pageCount' => (int)$pageCount,
'data' => $data,
]);
}
效果
前端完整代碼(參考,太長可不看)
<template>
<div>
<!--添加按鈕和模態框-->
<a-button type="primary" @click="showModal('add')">
添加
</a-button>
<!--對話框-->
<a-modal
:visible="visible"
:title= "modelTitle"
:confirm-loading="confirmLoading"
okText='確認'
cancel-text="取消"
@cancel="hideModel"
@ok="add"
>
<!--表單-->
<a-form-model :model="form">
<a-form-model-item label="用戶名">
<a-input v-model="form.username" />
</a-form-model-item>
<a-form-model-item label="密碼">
<a-input v-model="form.password" />
</a-form-model-item>
<a-form-model-item label="狀態">
<a-radio-group v-model="form.status">
<a-radio value="1">
啟用
</a-radio>
<a-radio value="0">
禁用
</a-radio>
</a-radio-group>
</a-form-model-item>
</a-form-model>
</a-modal>
<!--表格-->
<!--
:columns="columns" 表頭數據
:data-source="data" 表格數據
rowKey="id" id為 data 中的一個屬性
:loading="loading" 表格是否load
:pagination="pagination" 分頁參數
-->
<a-table :columns="columns" :data-source="data" rowKey="id" :loading="loading" :pagination="pagination" >
<span slot="status" slot-scope="text, record, index">
<div v-if="text == 1">
<a-button type="primary" @click="changeActive(text, record, index)">已啟用</a-button>
</div>
<div v-else>
<a-button type="danger" @click="changeActive(text, record, index)">已禁用</a-button>
</div>
</span>
<!--插槽一定要在表格組件標簽中-->
<!--定義插槽渲染-->
<!--
slot="action" 表示是在columns(某列)中的表頭值為action中插入標簽,往這個位置插入插槽span中間的內容
slot-scope="text, record, index"
text 表示當前行當前列的值
record 表示當前行的數據
index 表格索引
-->
<span slot="action" slot-scope="text, record, index">
<a-button type="primary" @click="edit(text, record, index)">編輯</a-button>
<a-button type="danger">刪除</a-button>
</span>
</a-table>
</div>
</template>
<script>
export default {
// 在實例中使用 components 屬性注冊需要用到的組件
//注冊組件
data() {
return {
//表格數據
data : [],
/**
* 表頭數據
* title 為表頭的標題
* dataIndex為列數據在數據項中對應的 key
* scopedSlots 對應插槽
*/
columns : [
{
title: '登錄用戶名',
dataIndex: 'username',
},
{
title: '昵稱',
dataIndex: 'nickname',
},
{
title: '狀態',
dataIndex: 'status',
scopedSlots: {customRender: 'status'},
},
{
title: '操作',
dataIndex: 'action',
//使用插槽
scopedSlots: {customRender: 'action'},
},
],
//表格load標志
loading : true,
//表格分頁參數
pagination: {
pageNo: 1,
pageSize: 10, // 默認每頁顯示數量
showSizeChanger: true, // 顯示可改變每頁數量
pageSizeOptions: ['10', '20', '50', '100'], // 每頁數量選項
showTotal: total => `共 ${total} 條數據`, // 顯示總數
onShowSizeChange: (current, pageSize) => this.changePageSize(current, pageSize), // 改變每頁數量時更新顯示
onChange:(page,pageSize)=>this.changePage(page,pageSize),//點擊頁碼事件
total:0 //總條數
},
//模態對話框標題
modelTitle: '',
//模態框是否顯示
visible: false,
//表單load
confirmLoading: false,
form : {
username : '',
password : '',
status : '1'
}
};
},
//頁面渲染之前,$el創建之后 去加載
mounted() {
//獲取左側菜單
this.getAdminList();
},
methods: {
//獲取管理員列表
getAdminList(param) {
//初始化分頁參數
if(param === undefined || param === null){
param = {
current : 1,
pageSize : 10
}
}
this.axios.get(process.env.VUE_APP_API_URL + this.urls.admin_list,{params: {
pageNow : param.current,
pageSize : param.pageSize,
}}).then((data) => {
//修改loading 狀態
this.loading = false;
//數據
this.data = data.data.data.data;
//分頁參數
/* this.pagination.current = data.data.data.pageNow;
this.pagination.pageSize = data.data.data.pageSize;
this.pagination.showTotal = data.data.data.lineCount;*/
this.pagination.total = data.data.data.lineCount;
console.log(this.pagination);
});
},
//點擊頁碼事件
changePage(page,pageSize) {
console.log(page, '當前頁.......');
console.log(pageSize, '每頁大小.......');
this.getAdminList({
current : page,
pageSize : pageSize
})
},
//每頁顯示數量改變的事件
changePageSize(current, pageSize){
console.log(current, '當前頁.......');
console.log(pageSize, '每頁大小.......');
this.getAdminList({
current : current,
pageSize : pageSize
})
},
//模態對話框的方法
showModal(type) {
//console.log(type, 'type........');
//設置對話框標題
type === 'add'? this.modelTitle = '添加管理員':this.modelTitle = '編輯管理員'
this.visible = true;
},
//關閉模態框
hideModel() {
this.visible = false;
this.resetForm();
},
//重置form狀態
resetForm(){
this.form = {
username : '',
password : '',
status : '1'
}
},
//確認添加
add(){
//發送請求
this.axios.post(process.env.VUE_APP_API_URL + this.urls.admin_add, this.form).then((data) => {
//重新刷新表格
this.data = this.getAdminList()
//恢復默認
this.resetForm();
//關閉按鈕的load狀態
this.confirmLoading = false;
//關閉模態框
this.visible = false;
});
},
//編輯
edit(text, record, index) {
//設置模態框的form表單的值和選中
this.form.username = record.username;
this.form.password = record.password;
this.form.status = ''+record.status;
//顯示模態框
this.showModal();
},
//改變狀態
changeActive(text, record, index) {
},
},
};
</script>
國際化
在前面的效果中可以看到,分頁選擇有英文,那怎么改成中文格式呢?
這就需要使用國際化了
https://www.antdv.com/components/locale-provider-cn/
國際化分兩種
局部國際化
例:
在要國際化的組件外面包裹
<a-locale-provider :locale="zhCN">
<!--表格-->
<!--
:columns="columns" 表頭數據
:data-source="data" 表格數據
rowKey="id" id為 data 中的一個屬性
:loading="loading" 表格是否load
:pagination="pagination" 分頁參數
-->
<a-table :columns="columns" :data-source="data" rowKey="id" :loading="loading" :pagination="pagination" >
<span slot="status" slot-scope="text, record, index">
<div v-if="text == 1">
<a-button type="primary" @click="changeActive(text, record, index)">已啟用</a-button>
</div>
<div v-else>
<a-button type="danger" @click="changeActive(text, record, index)">已禁用</a-button>
</div>
</span>
<!--插槽一定要在表格組件標簽中-->
<!--定義插槽渲染-->
<!--
slot="action" 表示是在columns(某列)中的表頭值為action中插入標簽,往這個位置插入插槽span中間的內容
slot-scope="text, record, index"
text 表示當前行當前列的值
record 表示當前行的數據
index 表格索引
-->
<span slot="action" slot-scope="text, record, index">
<a-button type="primary" @click="edit(text, record, index)">編輯</a-button>
<a-button type="danger">刪除</a-button>
</span>
</a-table>
</a-locale-provider>
script中引入並導出
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN';
data() {
return {
zhCN,
}
}
效果
全局國際化
找到app.vue
,使用
例:
<template>
<div id="app">
<!--<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>-->
<a-locale-provider :locale="zhCN">
<router-view/>
</a-locale-provider>
</div>
</template>
<script>
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN';
export default {
data(){
return {
zhCN,
}
}
}
</script>
關於LocaleProvider棄用
用locale-provider組件的控制台你會發現,有個警告
Warning: [antdv: LocaleProvider]
LocaleProvider
is deprecated. Please uselocale
withConfigProvider
instead
大概意思就是
警告:[antdv: LocaleProvider] ' LocaleProvider '已被棄用。請使用“locale”和“ConfigProvider”
這是因為LocaleProvider是1.x的國際化的實現,2.0版本已經提供了更好的方式,但是1.0的也是可以使用的
2.0全局國際化
https://2x.antdv.com/docs/vue/i18n-cn/
找到app.vue
,使用
例:
<template>
<div id="app">
<!--<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>-->
<a-config-provider :locale="locale">
<router-view/>
</a-config-provider>
</div>
</template>
<script>
import zhCN from 'ant-design-vue/es/locale/zh_CN';
export default {
data(){
return {
locale:zhCN,
}
}
}
</script>
效果
可以看到已經沒有任何警告了