如何使用ant-design-vue的Table組件
安裝腳手架工具
npm install -g @vue/cli
查看@vue/cli版本,vue -V。
使用Vue CLI新建項目
vue create antd-demo
下載ant-design-vue,ant-design-vue@2.1.6
npm install ant-design-vue@next --save
修改main.js,完整引入ant-design-vue所有組件及樣式
import { createApp } from 'vue'
import App from './App.vue'
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
createApp(App).use(Antd).mount('#app')修改HelloWorld.vue,使用Antd的Table組件
<template> ? <a-table :dataSource="dataSource" :columns="columns" /> </template>
<script>
? export default {
? ? name:"Helloworld",
? ? setup() {
? ? ? return {
? ? ? ? dataSource: [
? ? ? ? ? {
? ? ? ? ? ? key: '1',
? ? ? ? ? ? name: '胡彥斌',
? ? ? ? ? ? age: 32,
? ? ? ? ? ? address: '西湖區(qū)湖底公園1號',
? ? ? ? ? },
? ? ? ? ? {
? ? ? ? ? ? key: '2',
? ? ? ? ? ? name: '胡彥祖',
? ? ? ? ? ? age: 42,
? ? ? ? ? ? address: '西湖區(qū)湖底公園1號',
? ? ? ? ? },
? ? ? ? ],
? ? ? ? columns: [
? ? ? ? ? {
? ? ? ? ? ? title: '姓名',
? ? ? ? ? ? dataIndex: 'name',
? ? ? ? ? ? key: 'name',
? ? ? ? ? },
? ? ? ? ? {
? ? ? ? ? ? title: '年齡',
? ? ? ? ? ? dataIndex: 'age',
? ? ? ? ? ? key: 'age',
? ? ? ? ? },
? ? ? ? ? {
? ? ? ? ? ? title: '住址',
? ? ? ? ? ? dataIndex: 'address',
? ? ? ? ? ? key: 'address',
? ? ? ? ? },
? ? ? ? ],
? ? ? };
? ? },
? };
</script>

:columns="columns",columns是一個數(shù)組,用于指定列頭dataIndex值依次是:name、age和address,與dataSource每項的name、age和address對應(yīng)。title,dataIndex值對應(yīng)的列頭名稱name,對應(yīng)的列頭名稱是姓名age,對應(yīng)的列頭名稱是年齡address,對應(yīng)的列頭名稱是地址
key,Vue需要的key,如果已經(jīng)設(shè)置了唯一的dataIndex,可以忽略這個屬性:dataSource=dataSource,指定數(shù)據(jù)源dataSource是一個數(shù)組- 每項的name、age和address,與columns里dataIndex的值:name、age和address相對應(yīng)
修改HelloWorld.vue,使用Antd的Table組件
<template>
? <a-table :columns="columns" :data-source="data">
? ? <template #name="{ text }">
? ? ? <a>{{ text }}</a>
? ? </template>
? ? <template #customTitle>
? ? ? <span>
? ? ? ? <smile-outlined />
? ? ? ? Name
? ? ? </span>
? ? </template>
? ? <template #tags="{ text: tags }">
? ? ? <span>
? ? ? ? <a-tag
? ? ? ? ? v-for="tag in tags"
? ? ? ? ? :key="tag"
? ? ? ? ? :color="tag === 'loser' ? 'volcano' : tag.length > 5 ? 'geekblue' : 'green'"
? ? ? ? >
? ? ? ? ? {{ tag.toUpperCase() }}
? ? ? ? </a-tag>
? ? ? </span>
? ? </template>
? ? <template #action="{ record }">
? ? ? <span>
? ? ? ? <a>Invite 一 {{ record.name }}</a>
? ? ? ? <a-divider type="vertical" />
? ? ? ? <a>Delete</a>
? ? ? ? <a-divider type="vertical" />
? ? ? ? <a class="ant-dropdown-link">
? ? ? ? ? More actions
? ? ? ? ? <down-outlined />
? ? ? ? </a>
? ? ? </span>
? ? </template>
? </a-table>
</template><script lang="ts">
import { SmileOutlined, DownOutlined } from '@ant-design/icons-vue';
import { defineComponent } from 'vue';
const columns = [
? {
? ? dataIndex: 'name',
? ? key: 'name',
? ? slots: { title: 'customTitle', customRender: 'name' },
? },
? {
? ? title: 'Age',
? ? dataIndex: 'age',
? ? key: 'age',
? },
? {
? ? title: 'Address',
? ? dataIndex: 'address',
? ? key: 'address',
? },
? {
? ? title: 'Tags',
? ? key: 'tags',
? ? dataIndex: 'tags',
? ? slots: { customRender: 'tags' },
? },
? {
? ? title: 'Action',
? ? key: 'action',
? ? slots: { customRender: 'action' },
? },
];
const data = [
? {
? ? key: '1',
? ? name: 'John Brown',
? ? age: 32,
? ? address: 'New York No. 1 Lake Park',
? ? tags: ['nice', 'developer'],
? },
? {
? ? key: '2',
? ? name: 'Jim Green',
? ? age: 42,
? ? address: 'London No. 1 Lake Park',
? ? tags: ['loser'],
? },
? {
? ? key: '3',
? ? name: 'Joe Black',
? ? age: 32,
? ? address: 'Sidney No. 1 Lake Park',
? ? tags: ['cool', 'teacher'],
? },
];
export default defineComponent({
? setup() {
? ? return {
? ? ? data,
? ? ? columns,
? ? };
? },
? components: {
? ? SmileOutlined,
? ? DownOutlined,
? },
});
</script>
注意哈,ant-design-vue Table里:data-source與:dataSource是等效的。
要使用slots自定義樣式,就有必要了解下Vue里的$slots和Table組件的源碼。
$slots
插槽內(nèi)容可以在this.$slots中看到,舉個例子。
組件base-layout
<template> ? ? <header> ? ? ? ? <slot name="header"></slot> ? ? </header> ? ? <main> ? ? ? ? <slot name="default"></slot> ? ? </main> ? ? <footer> ? ? ? ? <slot name="footer"></slot> ? ? </footer> </template>
<script>
export default {
? ? name:"base-layout"
}
</script>App.vue
<template> ? <BaseLayout> ? ? <template #header> ? ? ? <p>Here is part one</p> ? ? </template> ? ? <template #default> ? ? ? <p>Here is part two</p> ? ? </template> ? ? <template #footer> ? ? ? <p>Here is part three</p> ? ? </template> ? </BaseLayout> </template>
<script>
import BaseLayout from "./components/base-layout.vue";
export default {
? name: 'App',
? components: {
? ? BaseLayout?
? }
}
</script><style>
#app {
? font-family: Avenir, Helvetica, Arial, sans-serif;
? -webkit-font-smoothing: antialiased;
? -moz-osx-font-smoothing: grayscale;
? text-align: center;
? color: #2c3e50;
? margin-top: 60px;
}
</style>main.js
import { createApp } from 'vue'
import App from './App.vue'
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
createApp(App).use(Antd).mount('#app');
現(xiàn)在我們修改base-layout.vue,使用this.$slots來訪問插槽內(nèi)容。
<template> ? ? <header> ? ? ? ? <slot name="header"></slot> ? ? </header> ? ? <main> ? ? ? ? <slot name="default"></slot> ? ? </main> ? ? <footer> ? ? ? ? <slot name="footer"></slot> ? ? </footer> </template>
<script>
export default {
? ? name:"base-layout",
? ? mounted:function(){
? ? ? ? console.log(this);
? ? ? ? console.log(this.$slots);
? ? ? ? console.log(this.$slots.header);
? ? ? ? console.log(this.$slots.header());
? ? ? ? console.log(this.$slots.header()[0].el);
? ? ? ? console.log(this.$slots.default()[0].el);
? ? ? ? console.log(this.$slots.footer()[0].el);
? ? }
}
</script>
Table組件相關(guān)源碼
node_modules/ant-design-vue/es/table/index.js
updateColumns(cols = []) {
const columns = [];
const { $slots, $scopedSlots } = this;
cols.forEach(col => {
const { slots = {}, scopedSlots = {}, ...restProps } = col;
const column = {
...restProps,
};
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];
}
});
// if (slotScopeName && $scopedSlots[slotScopeName]) {
// column.customRender = column.customRender || $scopedSlots[slotScopeName]
// }
if (col.children) {
column.children = this.updateColumns(column.children);
}
columns.push(column);
});
return columns;
}


只有滿足條件(column[key] === undefined && $slots[name]),才能使用作用域插槽來自定義表頭。本例中,dataIndex:'name'想自定義表頭,所以不能定義title屬性,而是在slots屬性中定義了title屬性。

node_modules/ant-design-vue/es/vc-table/src/TableCell.js
render() {
? const {
? ? record,
? ? indentSize,
? ? prefixCls,
? ? indent,
? ? index,
? ? expandIcon,
? ? column,
? ? component: BodyCell,
? } = this;
? const { dataIndex, customRender, className = '' } = column;
? const { transformCellText } = this.table;
? // We should return undefined if no dataIndex is specified, but in order to
? // be compatible with object-path's behavior, we return the record object instead.
? let text;
? if (typeof dataIndex === 'number') {
? ? text = get(record, dataIndex);
? } else if (!dataIndex || dataIndex.length === 0) {
? ? text = record;
? } else {
? ? text = get(record, dataIndex);
? }
? let tdProps = {
? ? props: {},
? ? attrs: {},
? ? on: {
? ? ? click: this.handleClick,
? ? },
? };
? let colSpan;
? let rowSpan;
? 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));
? }
? // Fix https://github.com/ant-design/ant-design/issues/1202
? if (isInvalidRenderCellText(text)) {
? ? text = null;
? }
? if (transformCellText) {
? ? text = transformCellText({ text, column, record, index });
? }
? const indentText = expandIcon ? (
? ? <span
? ? ? style={{ paddingLeft: `${indentSize * indent}px` }}
? ? ? class={`${prefixCls}-indent indent-level-${indent}`}
? ? />
? ) : null;
? if (rowSpan === 0 || colSpan === 0) {
? ? return null;
? }
? if (column.align) {
? ? tdProps.style = { textAlign: column.align, ...tdProps.style };
? }
? const cellClassName = classNames(className, column.class, {
? ? [`${prefixCls}-cell-ellipsis`]: !!column.ellipsis,
? ? // 如果有寬度,增加斷行處理
? ? // https://github.com/ant-design/ant-design/issues/13825#issuecomment-449889241
? ? [`${prefixCls}-cell-break-word`]: !!column.width,
? });
? if (column.ellipsis) {
? ? if (typeof text === 'string') {
? ? ? tdProps.attrs.title = text;
? ? } else if (text) {
? ? ? // const { props: textProps } = text;
? ? ? // if (textProps && textProps.children && typeof textProps.children === 'string') {
? ? ? // ? tdProps.attrs.title = textProps.children;
? ? ? // }
? ? }
? }
? return (
? ? <BodyCell class={cellClassName} {...tdProps}>
? ? ? {indentText}
? ? ? {expandIcon}
? ? ? {text}
? ? </BodyCell>
? );
}
其中,customRender是渲染函數(shù),用來對表中的值進(jìn)行自定義渲染。該函數(shù)接受4個參數(shù),分別是 text、 record、index和 column。

antd官網(wǎng)也有customRender的相關(guān)說明,如下

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue 組件內(nèi)獲取actions的response方式
今天小編就為大家分享一篇vue 組件內(nèi)獲取actions的response方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
在vue框架下使用指令vue add element安裝element報錯問題
這篇文章主要介紹了在vue框架下使用指令vue add element安裝element報錯問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10
基于vue和react的spa進(jìn)行按需加載的實現(xiàn)方法
這篇文章主要介紹了基于vue和react的spa進(jìn)行按需加載,需要的朋友可以參考下2018-09-09
vue實現(xiàn)兩個組件之間數(shù)據(jù)共享和修改操作
這篇文章主要介紹了vue實現(xiàn)兩個組件之間數(shù)據(jù)共享和修改操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11

