[Bug] @visactor/vtable 在合并单元格内自定义渲染使用 VGroup的react属性 会渲染多个相同的元素
Version
1.17.0
Link to Minimal Reproduction
https://visactor.io/vtable/demo-react/custom-layout/cell-custom-layout-dom
Steps to Reproduce
代码如下: // import * as ReactVTable from '@visactor/react-vtable';
const { useCallback, useRef, useState } = React; const { ListTable, ListColumn, Group, Text, Image } = ReactVTable; const { Avatar, Card, Space, Typography } = ArcoDesign; const { IconThumbUp, IconShareInternal, IconMore } = ArcoDesignIcon; const { Meta } = Card; const { VGroup, VText } = VTable;
const customLayout = (args) => { const { table, row, col, rect, dataValue, value } = args; console.log(dataValue, value); if (!table || row === undefined || col === undefined) { return null; } const { height, width } = rect || table.getCellRect(col, row); // const record = table.getRecordByCell(col, row);
const cellRange = table.getCellRange(col, row); let isMergeCell = false; if ( cellRange.start.col !== cellRange.end.col || cellRange.start.row !== cellRange.end.row ) { isMergeCell = true; }
const attribute = { width, height, display: 'flex', flexDirection: 'row', flexWrap: 'nowrap', alignItems: 'center', alignContent: 'center', }
if (isMergeCell) { attribute.react = { element:
return { renderDefault: false, rootContainer: ( <VGroup attribute={attribute} > <VText attribute={{ text: isMergeCell ? '' : value, fontSize: 16, fontWeight: '500', fill: '#000', wordBreak: 'break-word', maxLineWidth: width - 20, lineHeight: 20, wrap: true, autoWrapText: true, textBaseline: 'middle', }} ></VText> </VGroup> ) } }
function App() { const records = [ { bloggerId: 1, bloggerName: 'Virtual Anchor Xiaohua', bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/flower.jpg', introduction: 'Hi everyone, I am Xiaohua, the virtual host. I am a little fairy who likes games, animation and food. I hope to share happy moments with you through live broadcast.', fansCount: 400, worksCount: 10, viewCount: 5, city: 'Dream City', tags: ['game', 'anime', 'food'] }, { bloggerId: 2, bloggerName: 'Virtual anchor little wolf', bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg', introduction: 'Hello everyone, I am the virtual anchor Little Wolf. I like music, travel and photography, and I hope to explore the beauty of the world with you through live broadcast.', fansCount: 800, worksCount: 20, viewCount: 15, city: 'City of Music', tags: ['music', 'travel', 'photography'] }, { bloggerId: 3, bloggerName: 'Virtual anchor bunny', bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg', introduction: 'Hello everyone, I am the virtual anchor Xiaotu. I like painting, handicrafts and beauty makeup. I hope to share creativity and fashion with you through live broadcast.', fansCount: 600, worksCount: 15, viewCount: 10, city: 'City of Art', tags: ['painting', 'handmade', 'beauty makeup'] }, { bloggerId: 4, bloggerName: 'Virtual anchor kitten', bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg', introduction: 'Hello everyone, I am the virtual host Kitty. I am a lazy cat who likes dancing, fitness and cooking. I hope to live a healthy and happy life with everyone through the live broadcast.', fansCount: 1000, worksCount: 30, viewCount: 20, city: 'Health City', tags: ['dance', 'fitness', 'cooking'] }, { bloggerId: 5, bloggerName: 'Virtual anchor Bear', bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg', introduction: 'Hello everyone, I am the virtual host Xiaoxiong. A little wise man who likes movies, reading and philosophy, I hope to explore the meaning of life with you through live broadcast.', fansCount: 1200, worksCount: 25, viewCount: 18, city: 'City of Wisdom', tags: ['Movie', 'Literature'] }, { bloggerId: 6, bloggerName: 'Virtual anchor bird', bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bird.jpeg', introduction: 'Hello everyone, I am the virtual anchor Xiaoniao. I like singing, acting and variety shows. I hope to be happy with everyone through the live broadcast.', fansCount: 900, worksCount: 12, viewCount: 8, city: 'Happy City', tags: ['music', 'performance', 'variety'] } ];
return ( <ListTable records={records} height={900} // defaultRowHeight={80} onReady={table => { // eslint-disable-next-line no-undef // (window as any).tableInstance = table; }} ReactDOM={ReactDom} customMergeCell={(col, row, table) => { // console.log(col, row, table, table.getCellOriginRecord(col, row)); if (col === 2 && row === 1 || col === 3 && row === 1) { return { text: '合并单元格xxxxxxxxxxxxxxxxxxx', range: { start: { col: 2, row: 1, }, end: { col: 3, row: 1, } }, style: { bgColor: '#ccc', padding: [0, 0, 0, 0], }, enableCellPadding: false,
}
}
return undefined;
}}
>
<ListColumn field={'bloggerId'} title={'ID'} customLayout={customLayout} />
<ListColumn field={'bloggerName'} title={'Name'} width={220} customLayout={customLayout}>
</ListColumn>
<ListColumn field={'fansCount'} title={'Fan'} customLayout={customLayout}>
</ListColumn>
<ListColumn field={'worksCount'} title={'Work'} customLayout={customLayout} />
<ListColumn field={'viewCount'} title={'View'} customLayout={customLayout} />
</ListTable>
); }
const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID)); root.render(<App />);
// release react instance, do not copy window.customRelease = () => { root.unmount(); };
Current Behavior
合并单元格下使用VGroup的react属性会append多个相同的元素
Expected Behavior
合并单元格下使用VGroup的react属性只append一个元素
Environment
- OS:
- Browser:
- Framework:
Any additional comments?
No response