ant-design-vue中的table自定义格式渲染解析

目录
  • ant-design-vue中table自定义格式渲染
    • 1、直接调用对应插槽模板
    • 2、指定渲染函数
  • ant-design-vue快速上手指南+排坑
    • NO.1 表单组件
    • NO.2 表格(Table)
    • NO.3 Spin组件
    • 打包优化
    • 结语

ant-design-vue中table自定义格式渲染

一般业务开发中,难免会遇到将一些状态值(如 0 / 1)转化为相应的描述(如 关闭 / 开启),也可能是对日期时间的格式化,如下两图转化前后对比:

开始之前,需要注意的是,定义的 columns 一定要写在 data 中,否则在加载过程中由于渲染顺序会导致其中的渲染函数无法识别。

有两种方式修改:

1、直接调用对应插槽模板

<template>
  <div class="vehicle-list">
    <a-table :columns="columns" :data-source="data" bordered>
      <template slot="tradeState" slot-scope="state">
        {{ state === 1 ? '交易完成' : (state === 0 ? '等待交易' : '交易失败') }}
      </template>
      <template slot="tradeTime" slot-scope="time">
        {{ timeFormat(time) }}
      </template>
    </a-table>
  </div>
</template>

<script>
import moment from 'moment'

const columns = [
  {
    title: '交易状态',
    dataIndex: 'tradeState',
    // customRender: 'tradeState' -> 自定义 slot 属性名,对应模版中的 slot 属性,即这里自定义为啥,对应模版中的 slot 就要等于啥
    // 模板中对应的 slot-scope 属性可以用来传递三个参数(val,row,index),分别是当前值、当前行数据和当前索引
    scopedSlots: { customRender: 'tradeState' }
  },
  {
    title: '交易时间',
    dataIndex: 'tradeTime',
    scopedSlots: { customRender: 'tradeTime' }
  }
]

const data = [
  {
    key: '1',
    tradeState: 1,
    tradeTime: '2020-11-01T12:50:19+08:00'
  },
  {
    key: '2',
    tradeState: -1,
    tradeTime: '2020-11-02T18:06:32+08:00'
  },
  {
    key: '3',
    tradeState: 0,
    tradeTime: '2020-11-03T08:25:03+08:00'
  }
]

export default {
  name: 'VehicleList',
  data () {
    return {
      data,
      columns
    }
  },
  methods: {
    timeFormat (val) { // 时间格式化函数
      return moment(val).format('YYYY-MM-DD HH:mm:ss')
    }
  }
}
</script>

2、指定渲染函数

<template>
  <div class="vehicle-list" style="width: 50%">
    <a-table :columns="columns" :data-source="data" bordered></a-table>
  </div>
</template>

<script>
import moment from 'moment'

const columns = [
  {
    title: '交易状态',
    dataIndex: 'tradeState',
    customRender: (state) => { // customRender属性是一个方法,可接收三个参数(val,row,index),分别是当前值、当前行数据和当前索引,与方式 1 中模版的 slot-scope 属性传参类似
      return state === 1 ? '交易完成' : (state === 0 ? '等待交易' : '交易失败')
    }
  },
  {
    title: '交易时间',
    dataIndex: 'tradeTime',
    customRender: (time) => moment(time).format('YYYY-MM-DD HH:mm:ss')
  }
]

const data = [
  {
    key: '1',
    tradeState: 1,
    tradeTime: '2020-11-01T12:50:19+08:00'
  },
  {
    key: '2',
    tradeState: -1,
    tradeTime: '2020-11-02T18:06:32+08:00'
  },
  {
    key: '3',
    tradeState: 0,
    tradeTime: '2020-11-03T08:25:03+08:00'
  }
]

export default {
  name: 'VehicleList',
  data () {
    return {
      data,
      columns
    }
  }
}
</script>

对比以上,可以看出方式2代码更加简洁,且易读性更好。

ant-design-vue快速上手指南+排坑

公司要开发一个后台管理系统,对于UI库的选择上选择了颜值爆表的Ant-Design-Vue作为整个项目UI库,但谁曾想,暗中的坑一个接一个,文档也不怎么详细,可能习惯了element-ui的掘友们也许不怎么好适应,本文就带大家一起学习如何高效使用Ant-Design-Vue。

NO.1 表单组件

首先就来说说最常用的Form组件的正确使用姿势:

先来看官方一段话述:

第一、我们不推荐在Form中使用双向绑定,同一份数据可能在多处使用,如果使用双向绑定,那么数据的修改会同时同步到各个组件,但这并不是我们想要的, 你应该在表单提交成功或失败或确认时同步数据,使用非双向绑定的表单,你会拥有最大限度的控制数据修改/同步的权限。

第二、如果你不使用表单的自动校验/收集功能,即没有使用v-decorator修饰过的组件,你依然可以使用v-model

看了官方的建议后,我们愉快的使用v-decorator修饰input组件,代码如下:

<a-form-item>
          <a-input
            placeholder="账号"
            v-decorator="['account',{rules: [{ required: true,whitespace:true,message: '请输入您的登陆账号' }]}]"
            />
</a-form-item>

划重点:

v-decorator里的account可以理解为input的name值,后面{}对象可以配置校验规则,初始值等参数,这里需要注意的是使用了v-decorator的组件无法使用v-model,也无法设置value等与值有关的属性,否则报错

v-decorator会自动收集你表单里的数据到form对象里,所以别忘了在data中加上这句代码:

form: this.$form.createForm(this)

模板中这么写:

如何自定义表单校验规则

这里拿确认密码举例:

<a-input
       type="password"
       v-decorator="['new_password',{rules:[{required: true,whitespace:true,message: '请输入新密码'},{validator: handlePass}]}]"
/>
<a-input
        type="password"
        v-decorator="['confirm_password',{rules:[{required: true,whitespace:true,message: '请重复新密码'},{validator:handleConfirmPass}]}]"
/>

这里我们使用validator校验器自定义函数

handlePass(rule, value, callback) {
      this.password = value;
      callback();
},
handleConfirmPass(rule, value, callback) {
      if (this.password && this.password !== value) {
           callback('与新密码输入不一致');
      }
      callback();
},

这里需要注意callback()必须调用

这里的value就是对应表单输入了的值,然后知道了这些我们就可以写我们自己的业务逻辑了

做好的效果如图:

表单回显

我们在做编辑时首先需要通过后端接口读取到之前的数据,但是因为现在没有了v-model,那么我们该怎么办?

可以调用form对象中的setFieldsValue把后端返回的对象直接设置上去,如果是在mounted方法里必须加上$nextTick,不然会抛出警告说我们在表单未渲染好之前给予了数据

代码如图:

图中setFieldsInitialValue是设置表单初始值,如果表单中有重置按钮,就需要设置上,重置按钮调用this.form.resetFields()就可以重置form表单了

这个setFieldsValue方法会把传进去的对象的key和模板中v-decorator中的第一个参数比较,会自动把对应的值set进去。

提交表单

按钮加上html-type="submit"后点击会触发这个方法,这个方法校验表单中所有必填项没有问题后会自动帮我们把表单中所有带有v-decorator修饰的组件的值和name序列化好,我们就可以直接传给后端了。

NO.2 表格(Table)

我们的模板可以这么写:

ant-design-vue的表格自带分页,接下来我把上图中的参数挨个解释下,columns是单元格信息,我们可以把他导出为一个数组,如下图:

这里的title是用户看到的文字,dataIndex要和后台传过来的字段一致,不然数据不会显示出来,其次还提供了customRender和scopedSlots两种方式自定义内容,这里使用了第一种方式,但值得一提的是如果使用的是slot-scope方式,在模板中定义一个点击事件,想要获取到当前行的数据时,一定一定不要加dataIndex属性,否则会是undefined

看一个scopedSlots使用的例子:

可以看到上面定义columns时给action没有加dataIndex

我们继续看dataSource是什么,他就是你给table传递的数据

  • rowKey可以理解为时循环时需要的key(必有)
  • pagination初始化一个空对象
  • scroll定义表格可以横向滚动
  • handleTableChange是当分页数据发生改变时抛出的事件

为了简化操作,我这里封装了一个mixin,当页面中有table时直接混入mixin就支持分页和拉取数据的逻辑了,代码如下:

export const mixin = {
  data() {
    return {
      pagination: {},
      data: [],
    };
  },
  methods: {
    handleTableChange(pagination) {
      const pager = {...this.pagination};
      pager.current = pagination.current;
      this.pagination = pager;
      this.loadData({
        page: pagination.current
      });
    },
    async loadData(params = {}) {
      try {
        const {data: table_data, total, per_page} = await this.loadMethod('flush' in params ? {page: 1} : {page: 1, ...params});
        const pagination = {...this.pagination};
        pagination.total = total;
        pagination.pageSize = per_page;
        'flush' in params && (pagination.current = 1);
        this.data = table_data;
        this.pagination = pagination;
      } catch (e) {
        console.log(e);
      }
    }
  }
};

flush用于标识是否是插入新数据或者删除了数据,如果是我们直接把page重置为1返回第一页

我们在页面使用只需要以下几行代码:

import { getLog } from '@/api/api';
import { mixin } from '@/mixins';
export default {
  name: "log",
  mixins: [mixin],
  data() {
    return {
      columns,
      loadMethod: getLog
    };
  },
  mounted() {
    this.loadData();
  }
};

这样其他类似的组件也可以直接复用本逻辑。

NO.3 Spin组件

我们平时在后台管理系统中,ajax请求过程中都会出现全屏加载提示的遮罩层,做这个功能时我想到了这个组件,然后去官方文档查看,看到了如下图的操作方式:

然后粘贴到代码中,各种操作,没有任何反应,甚至有时候还来点小报错,Spin组件肯定是引入了,反正就是最后怎么操作都没成功,无奈之下,自己用了他的样式写了个Vue的Spin插件:

我们首先新建Loading.vue

<template>
  <div v-if="show" class="loading-container">
    <div class="loading-mask"></div>
    <div class="loading-content">
      <a-spin tip="正在加载数据中..." size="large">
      </a-spin>
    </div>
  </div>
</template>
<script>
export default {
  name: 'Loading',
  props: {
    show: Boolean,
  },
  data() {
    return {
    }
  }
}
</script>
<style lang="scss" scoped>
  .loading-container{
    position: relative;
    text-align: center;
    z-index:9999;
    .loading-mask{
      position: fixed;
      top:0;
      bottom:0;
      left:0;
      right:0;
      background-color:rgba(0,0,0,.7);
    }
    .loading-content{
      position: fixed;
      left: 50%;
      top: 50%;
      z-index: 300;
      transform: translate(-50%,-50%);
      text-align: center;
      color:#fff;
    }
  }
</style>

然后再新建Loading.js

import Vue from 'vue';
import loadingComponent from './Loading.vue';

const LoadingConstructor = Vue.extend(loadingComponent);

const instance = new LoadingConstructor({
  el: document.createElement('div')
});

instance.show = false; // 默认隐藏
const loading = {
  show() { // 显示方法
    instance.show = true;
    document.body.appendChild(instance.$el);
  },
  hide() { // 隐藏方法
    instance.show = false;
  }
};

export default {
  install() {
    if (!Vue.$loading) {
      Vue.$loading = loading;
    }
    Vue.mixin({
      created() {
        this.$loading = Vue.$loading;
      }
    });
  }
};

然后在main.js中

import loading from '@/components/Loading/loading.js';

Vue.use(loading);

然后我们就可以愉快的调用了:

Vue.$loading.show();

打包优化

首先就是用官方快速上手中提供的按需加载,这里不再赘述,使用之后还存在以下问题:

里面的moment.js,还有lodash,还有icon的dist居然占用了我们500KB的空间,这不能忍,那怎么办呢?

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),

我们首先忽略掉语言包,然后看看图标怎么优化:

 config.resolve.alias
      .set('@', resolve('src'))
      .set('@ant-design/icons/lib/dist$',resolve('src/icon.js'))

我们还需要在src文件夹下面加一个文件 icons.js

//自己项目里面用到的Icon
export {default as UserOutline} from '@ant-design/icons/lib/outline/UserOutline';
export {default as CloseCircleFill} from '@ant-design/icons/lib/fill/CloseCircleFill';
export {default as InfoCircleFill} from '@ant-design/icons/lib/fill/InfoCircleFill';
export {default as CheckCircleFill} from '@ant-design/icons/lib/fill/CheckCircleFill';

我们还可以开启gzip压缩等,使用DLL优化我们的打包速度,这些在这里就不再赘述了,社区有很多类似的贴子。

结语

那么对于ant-design-vue使用的前两天感觉不怎么顺手,现在只能说真香

其实这个UI库用习惯之后会发现好像Form表单的设计其实比v-model更好用,哈哈

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 如何在 ant 的table中实现图片的渲染操作

    如何在 ant 的table中实现图片的渲染 在使用react 的蚂蚁金服的ui库的时候,,平时用到的比较比较多的就是table组件,但是在ant官网上面,并没有在后台调取接口获取数据后,,如何将后台的http://lkjlkjlkj.jpg图片渲染到每一行的例子..只有一个render的方法...查阅了一些资料,作为一个不是很资深的前端来说,忙活了一上午,.实现了这个功能...记录一下... 这里是table的使用 <Table selectHandle={false} onCtrlClick

  • ant design vue中表格指定格式渲染方式

    注意点:定义的columns一定要写在data中,否则在加载过程中由于渲染顺序会导致其中的渲染函数无法识别 渲染方法1: 指定渲染函数: const columns = [ { title: '排名', dataIndex: 'key', customRender: renderContent // 渲染函数的规则 }, { title: '搜索关键词', dataIndex: 'keyword', customRender: (text, row, index) => { if (index

  • ant-design-vue动态表格合并案例

    目录 前言 数据格式 ant-desgin-vue表格提供的api 合并单元格算法实现 效果展示 前言 最近接到一个需求,要把后端传过来的数据动态展示在表格上面,并且支持前端筛选,相同数据进行单元格合并, 最终实现的效果如下: 数据格式 后端会返回给我们一个数组,数组的每一项格式是这样,在这个需求里,我们需要对 title,department,bugType 这三个字段相同的值的单元格进行合并 { fixCount: 0, id: 0, codeType: '新代码', bugType: 'u

  • 解决ant design vue 表格a-table二次封装,slots渲染的问题

    目的就是对a-table进行二次封装,但是在如何显示a-table的slot时遇到了问题,原本想法是在a-table内把$slots都渲染,期望在使用该组件时能正确渲染,然而...并不会正确渲染 <template> <a-table bordered :scroll="{ x: scrollX, y: 600 }" v-bind="{...$attrs, ...$props, ...{dataSource: body, columns: header}}&

  • ant-design-vue中的table自定义格式渲染解析

    目录 ant-design-vue中table自定义格式渲染 1.直接调用对应插槽模板 2.指定渲染函数 ant-design-vue快速上手指南+排坑 NO.1 表单组件 NO.2 表格(Table) NO.3 Spin组件 打包优化 结语 ant-design-vue中table自定义格式渲染 一般业务开发中,难免会遇到将一些状态值(如 0 / 1)转化为相应的描述(如 关闭 / 开启),也可能是对日期时间的格式化,如下两图转化前后对比: 开始之前,需要注意的是,定义的 columns 一定

  • Ant Design Vue中的table与pagination的联合使用方式

    目录 Ant Design Vue中table与pagination联合使用 ant.design.vue中table的使用说明 table的创建 table之columns table之dataSource table之loading table之scroll table之rowKey table之rowSelection table之customRow table之change Ant Design Vue中table与pagination联合使用 表格table使用链接:ant desig

  • ant design vue中日期选择框混合时间选择器的用法说明

    首先时间格式化用到moment方法,需要在页面中引入moment组件 import moment from 'moment' 结构代码: <a-date-picker style="width:100%" :getCalendarContainer="(triggerNode) => triggerNode.parentNode" format="YYYY-MM-DD HH:mm:ss" v-decorator="[ 'pu

  • Ant design vue中的联动选择取消操作

    项目中会遇到需求就是table表格中选中在侧边展示,侧边删除,table中选中取消的联动选中 ui框架:Ant design vue 组件:table 和 tag html中 <template v-for="tag in dataType"> <!-- key不能使用index --> <a-tag :key="tag.id" closable :afterClose="() => deleteDataType(tag

  • 解决ant design vue中树形控件defaultExpandAll设置无效的问题

    页面步骤: 1.设置a-tree标签 2.默认的treeNodes值设置为空数组 3.在mounted组件加载的时候给treeNodes的值赋值 结果: 设置defaultExpandAll无效,并不能展开所有节点 原因: defaultExpandAll 仅在组件第一次渲染时有效,不仅仅tree组件,其它组件的defaultXXX值都是这个行为, 可以自行搜索受控组件/非受控组件的概念.如果你想异步获取数据后展开全部结点,可以使用非受控方式: https://codepen.io/lovefe

  • ant design vue 表格table 默认勾选几项的操作

    为什么我同样的功能要用react .vue 都写一遍 ? 啊我真是不是闲的蛋疼啊(- o -)~zZ 在 ant design vue 中,表格的第一列是联动的选择框 截一张官方文档图,图示最后一排就是禁用状态 点击 checkbox 会触发onChange , 从而得到selectedRowKeys,selectedRowKeys就是选中的 key 数组. onChange: (selectedRowKeys, selectedRows) => { console.log(`selectedR

  • Ant design vue table 单击行选中 勾选checkbox教程

    最近了解Ant design 设计table 单击行选中checkedbox功能,相比于element的 @row-click 再触发toggleRowSelection,ant design的api就没那么清晰了,言归正传 期望:Ant design table 单击行选中 勾选checkedbox 实现: 单选: onClickRow(record) { return { on: { click: () => { let keys = []; keys.push(record.id); th

  • Ant Design Vue table中列超长显示...并加提示语的实例

    我就废话不多说了,大家还是直接看代码吧~ <template> <a-row class="a-left"> <a-row> <p class="a-title">今日考勤状况</p> <a-row type="flex" justify="space-around"> <a-col :span="4" class="b

  • ant design vue datepicker日期选择器中文化操作

    按照ant design vue官方说明,使用日期选择器需要在入口文件(main.js)全局设置语言: // 默认语言为 en-US,如果你需要设置其他语言,推荐在入口文件全局设置 locale import moment from 'moment'; import 'moment/locale/zh-cn'; moment.locale('zh-cn'); <a-date-picker :defaultValue="moment('2015-01-01', 'YYYY-MM-DD')&q

随机推荐