ant design vue 表格和国际化的使用
官方文档: 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>
效果
可以看到已经没有任何警告了