ant-design-vue中table自定义列
1. 使用背景
在项目中使用ant-vue的a-table控件过程中,需要显示序号列或者在列中显示图片,超链,按钮等UI信息。经过查询文档customCell和customRender可以实现以上需求,比如实现如下表格数据渲染

2. slots&scopedSlots作用
在查看文档过程中,在类型一栏中经常看到 xxx|slot |slot-scope 这样的描述信息。比如customRender在文档中的描述信息
customRender | 生成复杂数据的渲染函数.. | **Function(text, record, index) {}|slot-scope**
在最初一直以为在列中可以是如下配置的
// 公众号:小院不小 date 20210205 wx:464884492
const tableColumn = [
      {
        title: '游戏名称',
        dataIndex: 'title',
        customRender:'xxslot'
      }
]
这样定义后执行npm run serve在浏览器会出现customRender is not function 的错误信息。以及后来看到有如下写法
// 公众号:小院不小 date 20210205 wx:464884492
const tableColumn = [
      {
        title: '游戏名称',
        dataIndex: 'title',
        scopedSlots: {
          customRender: "customRender"
        }
      }
]
还有很长一段时间不明白scopedSlots这个对象的属性为啥是customRender, 还有其他的什么属性吗?当时知识还不完善没有理解到文档上使用 columns 时,可以通过该属性配置支持 slot-scope 的属性的含义
虽然知道怎么用了,但还是有必要了解下它是如何运行的。我们知道在vue中可以通过this.$slots、this.$scopedSlots分别访问静态插槽和作用域插槽。在文件components\table\index.jsx中可以找到组件库对scopedSlots、slots转换成具体函数的过程,代码如下
 // 公众号:小院不小 date 20210205 wx:464884492
 ...
 // 获取插槽
 const { $slots, $scopedSlots } = this;
 // 转换静态插槽
 Object.keys(slots).forEach(key => {
      const name = slots[key];
      if (column[key] === undefined && $slots[name]) {
        column[key] = $slots[name].length === 1 ? $slots[name][0] : $slots[name];
      }
    });
 // 转换动态插槽
 Object.keys(scopedSlots).forEach(key => {
  const name = scopedSlots[key];
  if (column[key] === undefined && $scopedSlots[name]) {
    column[key] = $scopedSlots[name];
  }
 });
从以上代码也可以知道,如果您定义如下的列配置,自定插槽会失效,以下代码该列会全部显示123
// 公众号:小院不小 date 20210205 wx:464884492
{
    title: "customRender|slot-scope",
    dataIndex: '',
    customRender: () => 123,
    scopedSlots: {
      customRender: "customRender"
    }
}
也就是说customRender定义成函数的优先级高于作用域插槽
3. customCell
customCell影响的是vnode中的属性信息,你可以改变当前列的样式等相关信息,在文件 components\vc-table\src\TableCell.jsx 对应代码片段
// 公众号:小院不小 date 20210205 wx:464884492
...
 if (column.customCell) {
  tdProps = mergeProps(tdProps, column.customCell(record, index));
}
...
 return (
  <BodyCell class={cellClassName} {...tdProps}>
    {indentText}
    {expandIcon}
    {text}
  </BodyCell>
);
所以这个对象可以传递值可以参考vue官方文档深入数据对象中的描述。你可以返回如下对改变当前列的字体大小和颜色
// 公众号:小院不小 date 20210205 wx:464884492
 return {
    style: {
      color: 'red',
      fontSize: '14px'
    }
 }
也可通过如下改变显示的内容
// 公众号:小院不小 date 20210205 wx:464884492
return {
  domProps: {
      innerHTML: record.title + "#" + (index + 1)
    }
}
4. customRender
customRender也可以影响当前列的显示信息,不过它更灵活。可以返回一段jsx获取返回一个类似customCell一样的属性信息。不过从代码来看,它只接收一下属性attrs、props、class、style、children,而且它的优先级也没有customCell优先级高。customRender可以是一个插槽,也可以是一个函数。
当作为插槽使用时代码应该如下所示
// 公众号:小院不小 date 20210205 wx:464884492
[{
  title: "customRender|slot-scope",
  dataIndex: '',
  scopedSlots: {
    customRender: "customRender"
  }
},{
  title: "customRender|slot-scope",
  dataIndex: '',
  slots: {
    customRender: "customRender"
  }
}]
从上边了解到的插槽知识可以知道作用域插槽的优先级高于静态插槽也就是说,在一个列中分别配置了键值相等的静态插槽和作用域插槽,将优先显示作用域插槽的内容
当作为函数使用时,代码应该如下所示
// 公众号:小院不小 date 20210205 wx:464884492
[{
  title: '游戏特点',
  dataIndex: 'desc',
  customRender: (text, record, index) => {
    if (index == 1) {
      return <div> {text} <span style="color:blue"> @小院不小</span></div>
    }
    return {
      attrs:{},
      props:{},
      class:{},
      style:{},
      children: text
    }
  }
}]
两种返回值组件通过isInvalidRenderCellText函数判断。判断是否是jsx的方式主要代码如下
// 公众号:小院不小 date 20210205 wx:464884492
function isValidElement(element) {
  return (
    element &&
    typeof element === 'object' &&
    'componentOptions' in element &&
    'context' in element &&
    element.tag !== undefined
  );
}
通过上边的说明,我们就能很好的使用customRender属性了。不过我们还是有必要了解一下,这段属性对应源代码逻辑。在文件components\vc-table\src\TableCell.jsx 对应的代码片段如下
// 公众号:小院不小 date 20210205 wx:464884492
if (customRender) {
  text = customRender(text, record, index, column);
  if (isInvalidRenderCellText(text)) {
    tdProps.attrs = text.attrs || {};
    tdProps.props = text.props || {};
    tdProps.class = text.class;
    tdProps.style = text.style;
    colSpan = tdProps.attrs.colSpan;
    rowSpan = tdProps.attrs.rowSpan;
    text = text.children;
  }
}
if (column.customCell) {
  tdProps = mergeProps(tdProps, column.customCell(record, index));
}
5. 总结
ant的组件很灵活,很多需要通过扩展来实现一些特殊的功能.customRender和customCell都可以实现自定义列信息。在什么场景下使用,还需要根据不同业务诉求。比如我要改变列字体,颜色等,我们就优先考虑customCell.根据上面的介绍这里有一个面试题代码如下
// 公众号:小院不小 date 20210205 wx:464884492
{
  title: "自定义列",
  dataIndex: '',
  customRender:()=>'函数渲染'
   scopedSlots: {
    customRender: "scopedSlots"
  },
  slots: {
    customRender: "slots"
  }
}
请问列自定义列最终渲染的内容是
- A 函数渲染
 - B scopedSlots
 - C slots
 
如果想知道答案或需要Demo源码请扫描下方的二维码,关注公众号[小院不小],回复ant-table获取.

ant-design-vue中table自定义列的更多相关文章
- react ,ant Design UI中table组件合并单元格并展开详情的问题
		
需求:购物车订单列表,如图: 一:单元格合并 遇到这种你会怎么办呢? 单元格合并? 还是其他的方法? 下面是我的处理方式,就是在table 组件的columns上处理,这里拿商品举例,其余的类似, ...
 - Ant Design Vue select下拉列表设置默认值
		
在项目中需要为Ant Design Vue 的 select 组件设置一个默认值,如下图所示的状态下拉选择框,默认选择全部 代码如下: <a-select v-model="query ...
 - Ant Design Pro中Transfer穿梭框的实际用法(与后端交互)
		
Ant Design Pro中Transfer穿梭框的实际用法(与后端交互) 该控件的属性以及属性的作用在ADP的官方文档中都有介绍,但没有讲如何与后端交互,本文旨在讲解该控件与后端的交互. Ant ...
 - Ant Design Vue Pro 项目实战-项目初始化(一)
		
写在前面 时间真快,转眼又是新的一年.随着前后端技术的不断更新迭代,尤其是前端,在目前前后端分离开发模式这样的一个大环境下,交互性.兼容性等传统的开发模式已经显得有些吃力.之前一直用的是react,随 ...
 - 基于Ant Design Vue封装一个表单控件
		
开源代码 https://github.com/naturefwvue/nf-vue3-ant 有缺点本来是写在最后的,但是博文写的似乎有点太长了,估计大家没时间往下看,于是就把有缺点写在前面了,不喜 ...
 - 使用ant design vue的日历组件,实现一个简单交易日与非交易日的切换
		
使用ant design vue的日历组件,实现一个简单交易日与非交易日的切换 需求: 日历区分交易日.非交易日 可以切换面板查看整年交易日信息 可以在手动调整交易日.非交易日 演示实例 序--使用软 ...
 - Vue3学习(二)之集成Ant Design Vue
		
一.集成Ant Design Vue npm install ant-design-vue@2.0.0-rc.3 --save 兼容性 Ant Design Vue 2.x 支持所有的现代浏览器. 如 ...
 - vue中可以自定义动画的前缀
		
vue中可以自定义动画的前缀1.只需在中加入name属性即可 <transition name="my"> <h6 v-if="flag2"& ...
 - Ant Design框架中不同的组件访问不同的models中的数据
		
Ant Design框架中不同的组件访问不同的models中的数据 本文记录了我在使用该框架的时候踩过的坑,方便以后查阅. 一.models绑定 在某个组件(控件或是页面),要想从某个models中获 ...
 
随机推荐
- hdu4028 The time of a day (map+dp)
			
Problem Description There are no days and nights on byte island, so the residents here can hardly de ...
 - Pyqt5 安装
			
window 安装PyQt5 pip install pyqt5 pip install pyqt5-tools (安装常用的Qt工具) 添加环境变量 变量名: QT_QPA_PLATFORM_PL ...
 - C# TCP应用编程三 异步TCP应用编程
			
利用TcpListener和TcpClient类在同步方式下接收.发送数据以及监听客户端连接时,在操作没有完成之前一直处于阻塞状态,这对于接受.发送数据量不大的情况或者操作勇士较短的情况下是比较方便的 ...
 - linux环境下使用jmeter进行分布式测试
			
1.前言 熟练使用jmeter进行性能测试的工程师都知道,jmeter的客户端性能是有点差的.这会导致一个问题,其客户端的性能损耗会干扰到性能测试的结果,而且当线程数/并发大到一定程度时,客户端性能会 ...
 - Pangolin 安装测试 Installation & Examination (Ubuntu 20.04)
			
Pangolin 安装测试 Installation & Examination (Ubuntu 20.04) 如题所述,这是一个比较轻松的 Pangolin 安装配置方法,同样是基于 WSL ...
 - C# 类 (11) - Const
			
Const variable 变量 ,值可变的constant 常量,不可变,C# 里关键字是const当我们定义一个常量的时候,需要立马赋值,以后不能再改这个量了我们可以把常量定义在 method ...
 - PyQt5笔记
			
PyQt5 窗口类继承QMainWindow. 1.消息盒子QMessageBox 弹出一个窗口,根据选择的不同执行不同的操作.比如点击关闭后,实用消息盒子确认是否关闭. # 关闭QWidget将产生 ...
 - python文件持久化存储
			
文件持久化存储 目录 文件持久化存储 脑图 文件的操作 with 语句 OS模块 json模块 存储为Excel文件 脑图 文件的操作 import os import platform # 1. 获 ...
 - 深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!
			
英文:https://arpitbhayani.me/blogs/string-interning 作者:arpit 译者:豌豆花下猫("Python猫"公众号作者) 声明:本翻译 ...
 - 101道Numpy、Pandas练习题
			
无论是数据分析还是机器学习,数据的预处理必不可少. 其中最常用.最基础的Python库非numpy和pandas莫属,很多初学者可能看了很多教程,但是很快就把用法忘光了. 光看不练假把式,今天向大家推 ...