ant-design-vue中table自定义列

1. 使用背景

在项目中使用ant-vuea-table控件过程当中,须要显示序号列或者在列中显示图片,超链,按钮等UI信息。通过查询文档customCellcustomRender能够实现以上需求,好比实现以下表格数据渲染javascript

2. slots&scopedSlots做用

在查看文档过程当中,在类型一栏中常常看到 xxx|slot |slot-scope 这样的描述信息。好比customRender在文档中的描述信息html

属性 说明 类型
customRender 生成复杂数据的渲染函数.. Function(text, record, index){}|slot-scope

在最初一直觉得在列中能够是以下配置的vue

// 公众号:小院不小 date 20210205 wx:464884492
const tableColumn = [
      {
        title: '游戏名称',
        dataIndex: 'title',
        customRender:'xxslot'
      }
]
复制代码

这样定义后执行npm run serve在浏览器会出现customRender is not function 的错误信息。以及后来看到有以下写法java

// 公众号:小院不小 date 20210205 wx:464884492
const tableColumn = [
      {
        title: '游戏名称',
        dataIndex: 'title',
        scopedSlots: {
          customRender: "customRender"
        }
      }
]
复制代码

还有很长一段时间不明白scopedSlots这个对象的属性为啥是customRender, 还有其余的什么属性吗?当时知识还不完善没有理解到文档上使用 columns 时,能够经过该属性配置支持 slot-scope 的属性的含义node

虽然知道怎么用了,但仍是有必要了解下它是如何运行的。咱们知道在vue中能够经过this.$slotsthis.$scopedSlots分别访问静态插槽和做用域插槽。在文件components\table\index.jsx中能够找到组件库对scopedSlotsslots转换成具体函数的过程,代码以下面试

// 公众号:小院不小 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];
  }
 });
复制代码

从以上代码也能够知道,若是您定义以下的列配置,自定插槽会失效,如下代码该列会所有显示123npm

// 公众号:小院不小 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 对应代码片断markdown

// 公众号:小院不小 date 20210205 wx:464884492
...
 if (column.customCell) {
  tdProps = mergeProps(tdProps, column.customCell(record, index));
}
...
 return (
  <BodyCell class={cellClassName} {...tdProps}> {indentText} {expandIcon} {text} </BodyCell>
);    
复制代码

因此这个对象能够传递值能够参考vue官方文档深刻数据对象中的描述。你能够返回以下对改变当前列的字体大小和颜色dom

// 公众号:小院不小 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同样的属性信息。不过从代码来看,它只接收一下属性attrspropsclassstylechildren,并且它的优先级也没有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的组件很灵活,不少须要经过扩展来实现一些特殊的功能.customRendercustomCell均可以实现自定义列信息。在什么场景下使用,还须要根据不一样业务诉求。好比我要改变列字体,颜色等,咱们就优先考虑customCell.根据上面的介绍这里有一个面试题代码以下

// 公众号:小院不小 date 20210205 wx:464884492
{
  title: "自定义列",
  dataIndex: '',
  customRender:()=>'函数渲染'
   scopedSlots: {
    customRender: "scopedSlots"
  },
  slots: {
    customRender: "slots"
  }
}
复制代码

请问列自定义列最终渲染的内容是

  • A 函数渲染
  • B scopedSlots
  • C slots

若是想知道答案或须要Demo源码请扫描下方的二维码,关注公众号[小院不小],回复ant-table获取.

相关文章
相关标签/搜索