ant design vue 表格和国际化的使用

官方文档: https://www.antdv.com/components/table-cn/

注意 #

在 Table 中,dataSourcecolumns 里的数据值都需要指定 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>

效果

image-20201111165104824

给最后一列加上编辑和删除按钮

如果想在最后一列渲染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)
        }
    }
};

效果

image-20201111170113093

完整代码

<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 set rowKey to an unique primary key.]

image-20201117111857571

这时候你如果数据是静态,直接加上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,
    ]);
}

效果

image-20201124101038799

前端完整代码(参考,太长可不看)

<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,
    }
}

效果

image-20201124104817516

全局国际化

找到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 use locale with ConfigProvider 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>

效果

image-20201124110407102

可以看到已经没有任何警告了

posted @ 2020-11-11 17:03  makalo  阅读(5341)  评论(19编辑  收藏  举报