VisActor / VTable

VTable is not just a high-performance multidimensional data analysis table, but also a grid artist that creates art between rows and columns.
https://visactor.io/vtable
MIT License
1.8k stars 166 forks source link

[Bug] react 自定义单元格,动态usestate 设置列的时候,table会报错(在设置行号后会出现,rowSeriesNumber={{ title: '序号', width: 60 }}) #2375

Closed TankTao closed 2 months ago

TankTao commented 2 months ago

Version

1.0.0

Link to Minimal Reproduction

https://visactor.io/vtable/demo-react/custom-layout/cell-custom-component

Steps to Reproduce

具体代码如下,设置序号后,页面加载后,手动设置colums后,页面会报错,

rowSeriesNumber={{ title: '序号', width: 60 }} 不设置这个还不会报错,设置后table就崩了

你们这个 线上代码复现,还不支持usestate,你们看看,我用的你们自定义组件的列子 https://visactor.io/vtable/demo-react/custom-layout/cell-custom-component

报错信息如下

1 2


// import * as ReactVTable from '@visactor/react-vtable';

const VGroup = ReactVTable.Group;
const VText = ReactVTable.Text;
const VImage = ReactVTable.Image;
const VTag = ReactVTable.Tag;
const { useCallback, useRef, useState } = React;
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']
  }
];

const CustomLayoutComponent = (props) => {
  const { table, row, col, rect, text } = props;
  if (!table || row === undefined || col === undefined) {
    return null;
  }
  const { height, width } = rect || table.getCellRect(col, row);
  const record = table.getRecordByRowCol(col, row);

  const [hoverTitle, setHoverTitle] = React.useState(false);
  const [hoverIcon, setHoverIcon] = React.useState(false);
  const groupRef = React.useRef(null);

  return (
    <VGroup
      attribute={{
        id: 'container',
        width,
        height,
        display: 'flex',
        flexWrap: 'nowrap',
        justifyContent: 'flex-start',
        alignContent: 'center'
      }}
      ref={groupRef}
    >
      <VGroup
        attribute={{
          id: 'container-left',
          width: 60,
          height,
          fill: 'red',
          opacity: 0.1,
          display: 'flex',
          justifyContent: 'space-around',
          alignItems: 'center'
        }}
      >
        <VImage
          attribute={{
            id: 'icon0',
            width: 50,
            height: 50,
            image: record.bloggerAvatar,
            cornerRadius: 25
          }}
        ></VImage>
      </VGroup>
      <VGroup
        id="container-right"
        attribute={{
          id: 'container-right',
          width: width - 60,
          height,
          fill: 'yellow',
          opacity: 0.1,
          display: 'flex',
          flexWrap: 'nowrap',
          flexDirection: 'column',
          justifyContent: 'space-around',
          alignItems: 'center'
        }}
      >
        <VGroup
          attribute={{
            id: 'container-right-top',
            fill: 'red',
            opacity: 0.1,
            width: width - 60,
            height: height / 2,
            display: 'flex',
            flexWrap: 'wrap',
            justifyContent: 'flex-start',
            alignItems: 'center'
          }}
        >
          <VText
            attribute={{
              id: 'bloggerName',
              text: record.bloggerName,
              fontSize: 13,
              fontFamily: 'sans-serif',
              fill: hoverTitle ? 'red' :  'black',
              textAlign: 'left',
              textBaseline: 'top',
              boundsPadding: [0, 0, 0, 10]
            }}
            onMouseEnter={(event) => {
              setHoverTitle(true);
              event.currentTarget.stage.renderNextFrame();
            }}
            onMouseLeave={(event) => {
              setHoverTitle(false);
              event.currentTarget.stage.renderNextFrame();
            }}
          ></VText>
          <VImage
            attribute={{
              id: 'location-icon',
              width: 15,
              height: 15,
              image:
                '<svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"><path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"></path><path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"></path><path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"></path></svg>',
              boundsPadding: [0, 0, 0, 10],
              cursor: 'pointer',
              background: hoverIcon ? {
                fill: '#ccc',
                cornerRadius: 5,
                expandX: 1,
                expandY: 1
              } : undefined
            }}

            onMouseEnter={event => {
              setHoverIcon(true);
              event.currentTarget.stage.renderNextFrame();
            }}
            onMouseLeave={event => {
              setHoverIcon(false);
              event.currentTarget.stage.renderNextFrame();
            }}
          ></VImage>
          <VText
            attribute={{
              id: 'locationName',
              text: record.city,
              fontSize: 11,
              fontFamily: 'sans-serif',
              fill: '#6f7070',
              textAlign: 'left',
              textBaseline: 'top'
            }}
          ></VText>
        </VGroup>
        <VGroup
          attribute={{
            id: 'container-right-bottom',
            fill: 'green',
            opacity: 0.1,
            width: width - 60,
            height: height / 2,
            display: 'flex',
            flexWrap: 'wrap',
            justifyContent: 'flex-start',
            alignItems: 'center'
          }}
        >
          {record.tags.length
            ? record.tags.map((str, i) => (
                // <VText attribute={{
                //   text: str,
                //   fontSize: 10,
                //   fontFamily: 'sans-serif',
                //   fill: 'rgb(51, 101, 238)',
                //   textAlign: 'left',
                //   textBaseline: 'rop',
                // boundsPadding: [0, 0, 0, 10],
                // }}></VText>
                <VTag
                  key={i}
                  textStyle={{
                    fontSize: 10,
                    fontFamily: 'sans-serif',
                    fill: 'rgb(51, 101, 238)'
                    // textAlign: 'left',
                    // textBaseline: 'rop',
                  }}
                  panelStyle={{
                    visible: true,
                    fill: '#e6fffb',
                    lineWidth: 1,
                    cornerRadius: 4
                  }}
                  boundsPadding={[0, 0, 0, 10]}
                >{str}</VTag>
              ))
            : null}
        </VGroup>
      </VGroup>
    </VGroup>
  );
}
![2](https://github.com/user-attachments/assets/fe22c157-4e5d-4330-8820-57516f6c59ee)
![1](https://github.com/user-attachments/assets/27f1add5-1820-4bef-b932-fc9e4e0722cf)
const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID));
const [columns, setColumns] = useState([{
  field: 'bloggerName',
  title: 'bloggerName'
},{
    field: 'bloggerId',
  title: 'bloggerId'
}]);

root.render(
  <div>
    <button onClick={()=> {
      setColumns(...columns,...columns)
    }}>ceshi</button>

  <ReactVTable.ListTable records={records} defaultRowHeight={80} height={'500px'} rowSeriesNumber={{ title: '序号', width: 60 }}>
    {columns.map((item)=> {
      return (<ReactVTable.ListColumn field={item.field} title={item.title} width={330} disableHover={true}>
        <CustomLayoutComponent role={'custom-layout'} />
      </ReactVTable.ListColumn>)
    })}

  </ReactVTable.ListTable>
  </div>
);

// release openinula instance, do not copy
window.customRelease = () => {
  root.unmount();
};

Current Behavior

具体代码如下,设置序号后,页面加载后,手动设置colums后,页面会报错,

rowSeriesNumber={{ title: '序号', width: 60 }} 不设置这个还不会报错,设置后table就崩了

你们这个 线上代码复现,还不支持usestate,你们看看,我用的你们自定义组件的列子 https://visactor.io/vtable/demo-react/custom-layout/cell-custom-component

报错信息如下

1 2


// import * as ReactVTable from '@visactor/react-vtable';

const VGroup = ReactVTable.Group;
const VText = ReactVTable.Text;
const VImage = ReactVTable.Image;
const VTag = ReactVTable.Tag;
const { useCallback, useRef, useState } = React;
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']
  }
];

const CustomLayoutComponent = (props) => {
  const { table, row, col, rect, text } = props;
  if (!table || row === undefined || col === undefined) {
    return null;
  }
  const { height, width } = rect || table.getCellRect(col, row);
  const record = table.getRecordByRowCol(col, row);

  const [hoverTitle, setHoverTitle] = React.useState(false);
  const [hoverIcon, setHoverIcon] = React.useState(false);
  const groupRef = React.useRef(null);

  return (
    <VGroup
      attribute={{
        id: 'container',
        width,
        height,
        display: 'flex',
        flexWrap: 'nowrap',
        justifyContent: 'flex-start',
        alignContent: 'center'
      }}
      ref={groupRef}
    >
      <VGroup
        attribute={{
          id: 'container-left',
          width: 60,
          height,
          fill: 'red',
          opacity: 0.1,
          display: 'flex',
          justifyContent: 'space-around',
          alignItems: 'center'
        }}
      >
        <VImage
          attribute={{
            id: 'icon0',
            width: 50,
            height: 50,
            image: record.bloggerAvatar,
            cornerRadius: 25
          }}
        ></VImage>
      </VGroup>
      <VGroup
        id="container-right"
        attribute={{
          id: 'container-right',
          width: width - 60,
          height,
          fill: 'yellow',
          opacity: 0.1,
          display: 'flex',
          flexWrap: 'nowrap',
          flexDirection: 'column',
          justifyContent: 'space-around',
          alignItems: 'center'
        }}
      >
        <VGroup
          attribute={{
            id: 'container-right-top',
            fill: 'red',
            opacity: 0.1,
            width: width - 60,
            height: height / 2,
            display: 'flex',
            flexWrap: 'wrap',
            justifyContent: 'flex-start',
            alignItems: 'center'
          }}
        >
          <VText
            attribute={{
              id: 'bloggerName',
              text: record.bloggerName,
              fontSize: 13,
              fontFamily: 'sans-serif',
              fill: hoverTitle ? 'red' :  'black',
              textAlign: 'left',
              textBaseline: 'top',
              boundsPadding: [0, 0, 0, 10]
            }}
            onMouseEnter={(event) => {
              setHoverTitle(true);
              event.currentTarget.stage.renderNextFrame();
            }}
            onMouseLeave={(event) => {
              setHoverTitle(false);
              event.currentTarget.stage.renderNextFrame();
            }}
          ></VText>
          <VImage
            attribute={{
              id: 'location-icon',
              width: 15,
              height: 15,
              image:
                '<svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"><path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"></path><path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"></path><path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"></path></svg>',
              boundsPadding: [0, 0, 0, 10],
              cursor: 'pointer',
              background: hoverIcon ? {
                fill: '#ccc',
                cornerRadius: 5,
                expandX: 1,
                expandY: 1
              } : undefined
            }}

            onMouseEnter={event => {
              setHoverIcon(true);
              event.currentTarget.stage.renderNextFrame();
            }}
            onMouseLeave={event => {
              setHoverIcon(false);
              event.currentTarget.stage.renderNextFrame();
            }}
          ></VImage>
          <VText
            attribute={{
              id: 'locationName',
              text: record.city,
              fontSize: 11,
              fontFamily: 'sans-serif',
              fill: '#6f7070',
              textAlign: 'left',
              textBaseline: 'top'
            }}
          ></VText>
        </VGroup>
        <VGroup
          attribute={{
            id: 'container-right-bottom',
            fill: 'green',
            opacity: 0.1,
            width: width - 60,
            height: height / 2,
            display: 'flex',
            flexWrap: 'wrap',
            justifyContent: 'flex-start',
            alignItems: 'center'
          }}
        >
          {record.tags.length
            ? record.tags.map((str, i) => (
                // <VText attribute={{
                //   text: str,
                //   fontSize: 10,
                //   fontFamily: 'sans-serif',
                //   fill: 'rgb(51, 101, 238)',
                //   textAlign: 'left',
                //   textBaseline: 'rop',
                // boundsPadding: [0, 0, 0, 10],
                // }}></VText>
                <VTag
                  key={i}
                  textStyle={{
                    fontSize: 10,
                    fontFamily: 'sans-serif',
                    fill: 'rgb(51, 101, 238)'
                    // textAlign: 'left',
                    // textBaseline: 'rop',
                  }}
                  panelStyle={{
                    visible: true,
                    fill: '#e6fffb',
                    lineWidth: 1,
                    cornerRadius: 4
                  }}
                  boundsPadding={[0, 0, 0, 10]}
                >{str}</VTag>
              ))
            : null}
        </VGroup>
      </VGroup>
    </VGroup>
  );
}
![2](https://github.com/user-attachments/assets/fe22c157-4e5d-4330-8820-57516f6c59ee)
![1](https://github.com/user-attachments/assets/27f1add5-1820-4bef-b932-fc9e4e0722cf)
const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID));
const [columns, setColumns] = useState([{
  field: 'bloggerName',
  title: 'bloggerName'
},{
    field: 'bloggerId',
  title: 'bloggerId'
}]);

root.render(
  <div>
    <button onClick={()=> {
      setColumns(...columns,...columns)
    }}>ceshi</button>

  <ReactVTable.ListTable records={records} defaultRowHeight={80} height={'500px'} rowSeriesNumber={{ title: '序号', width: 60 }}>
    {columns.map((item)=> {
      return (<ReactVTable.ListColumn field={item.field} title={item.title} width={330} disableHover={true}>
        <CustomLayoutComponent role={'custom-layout'} />
      </ReactVTable.ListColumn>)
    })}

  </ReactVTable.ListTable>
  </div>
);

// release openinula instance, do not copy
window.customRelease = () => {
  root.unmount();
};

Expected Behavior

希望设置序号后,动态的添加或者减少列数时候,table正常显示,能渲染

Environment

- OS:
- Browser:
- Framework:  @visactor/react-vtable' @visactor/vtable 1.5.3;

Any additional comments?

No response

Rui-Sun commented 2 months ago

20240904180035_rec_ 试了一下,最新版是没问题的,可以升级一下版本

Rui-Sun commented 2 months ago

测试代码

// import * as ReactVTable from '@visactor/react-vtable';

const VGroup = ReactVTable.Group;
const VText = ReactVTable.Text;
const VImage = ReactVTable.Image;
const VTag = ReactVTable.Tag;
const { useCallback, useRef, useState } = React;
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']
  }
];

const CustomLayoutComponent = (props) => {
  const { table, row, col, rect, text } = props;
  if (!table || row === undefined || col === undefined) {
    return null;
  }
  const { height, width } = rect || table.getCellRect(col, row);
  const record = table.getRecordByRowCol(col, row);

  const [hoverTitle, setHoverTitle] = React.useState(false);
  const [hoverIcon, setHoverIcon] = React.useState(false);
  const groupRef = React.useRef(null);

  return (
    <VGroup
      attribute={{
        id: 'container',
        width,
        height,
        display: 'flex',
        flexWrap: 'nowrap',
        justifyContent: 'flex-start',
        alignContent: 'center'
      }}
      ref={groupRef}
    >
      <VGroup
        attribute={{
          id: 'container-left',
          width: 60,
          height,
          fill: 'red',
          opacity: 0.1,
          display: 'flex',
          justifyContent: 'space-around',
          alignItems: 'center'
        }}
      >
        <VImage
          attribute={{
            id: 'icon0',
            width: 50,
            height: 50,
            image: record.bloggerAvatar,
            cornerRadius: 25
          }}
        ></VImage>
      </VGroup>
      <VGroup
        id="container-right"
        attribute={{
          id: 'container-right',
          width: width - 60,
          height,
          fill: 'yellow',
          opacity: 0.1,
          display: 'flex',
          flexWrap: 'nowrap',
          flexDirection: 'column',
          justifyContent: 'space-around',
          alignItems: 'center'
        }}
      >
        <VGroup
          attribute={{
            id: 'container-right-top',
            fill: 'red',
            opacity: 0.1,
            width: width - 60,
            height: height / 2,
            display: 'flex',
            flexWrap: 'wrap',
            justifyContent: 'flex-start',
            alignItems: 'center'
          }}
        >
          <VText
            attribute={{
              id: 'bloggerName',
              text: record.bloggerName,
              fontSize: 13,
              fontFamily: 'sans-serif',
              fill: hoverTitle ? 'red' :  'black',
              textAlign: 'left',
              textBaseline: 'top',
              boundsPadding: [0, 0, 0, 10]
            }}
            onMouseEnter={(event) => {
              setHoverTitle(true);
              event.currentTarget.stage.renderNextFrame();
            }}
            onMouseLeave={(event) => {
              setHoverTitle(false);
              event.currentTarget.stage.renderNextFrame();
            }}
          ></VText>
          <VImage
            attribute={{
              id: 'location-icon',
              width: 15,
              height: 15,
              image:
                '<svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"><path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"></path><path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"></path><path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"></path></svg>',
              boundsPadding: [0, 0, 0, 10],
              cursor: 'pointer',
              background: hoverIcon ? {
                fill: '#ccc',
                cornerRadius: 5,
                expandX: 1,
                expandY: 1
              } : undefined
            }}

            onMouseEnter={event => {
              setHoverIcon(true);
              event.currentTarget.stage.renderNextFrame();
            }}
            onMouseLeave={event => {
              setHoverIcon(false);
              event.currentTarget.stage.renderNextFrame();
            }}
          ></VImage>
          <VText
            attribute={{
              id: 'locationName',
              text: record.city,
              fontSize: 11,
              fontFamily: 'sans-serif',
              fill: '#6f7070',
              textAlign: 'left',
              textBaseline: 'top'
            }}
          ></VText>
        </VGroup>
        <VGroup
          attribute={{
            id: 'container-right-bottom',
            fill: 'green',
            opacity: 0.1,
            width: width - 60,
            height: height / 2,
            display: 'flex',
            flexWrap: 'wrap',
            justifyContent: 'flex-start',
            alignItems: 'center'
          }}
        >
          {record.tags.length
            ? record.tags.map((str, i) => (
                // <VText attribute={{
                //   text: str,
                //   fontSize: 10,
                //   fontFamily: 'sans-serif',
                //   fill: 'rgb(51, 101, 238)',
                //   textAlign: 'left',
                //   textBaseline: 'rop',
                // boundsPadding: [0, 0, 0, 10],
                // }}></VText>
                <VTag
                  key={i}
                  textStyle={{
                    fontSize: 10,
                    fontFamily: 'sans-serif',
                    fill: 'rgb(51, 101, 238)'
                    // textAlign: 'left',
                    // textBaseline: 'rop',
                  }}
                  panelStyle={{
                    visible: true,
                    fill: '#e6fffb',
                    lineWidth: 1,
                    cornerRadius: 4
                  }}
                  boundsPadding={[0, 0, 0, 10]}
                >{str}</VTag>
              ))
            : null}
        </VGroup>
      </VGroup>
    </VGroup>
  );
}

const App = () => {
const [columns, setColumns] = React.useState([{
  field: 'bloggerName',
  title: 'bloggerName'
},{
    field: 'bloggerId',
  title: 'bloggerId'
}]);

return (
  <div>
    <button onClick={()=> { 
      setColumns([...columns,...columns]) 
    }}>ceshi</button>

  <ReactVTable.ListTable
    records={records}
    defaultRowHeight={80}
    height={'500px'}
    rowSeriesNumber={{ title: '序号', width: 60 }}
  >
    {columns.map((item)=> {
      return (<ReactVTable.ListColumn field={item.field} title={item.title} width={330} disableHover={true}>
        <CustomLayoutComponent role={'custom-layout'} />
      </ReactVTable.ListColumn>)
    })}

  </ReactVTable.ListTable>
  </div>
)
}
const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID));

root.render(
  <App/>
);

// release openinula instance, do not copy
window.customRelease = () => {
  root.unmount();
};
TankTao commented 2 months ago

这个代码,在你们网页上是执行不了的吧,执行就会报错,识别不了usestate

---原始邮件--- 发件人: @.> 发送时间: 2024年9月4日(周三) 晚上6:02 收件人: @.>; 抄送: @.**@.>; 主题: Re: [VisActor/VTable] [Bug] react 自定义单元格,动态usestate 设置列的时候,table会报错(在设置行号后会出现,rowSeriesNumber={{ title: '序号', width: 60 }}) (Issue #2375)

测试代码 // import * as ReactVTable from @.*/react-vtable'; const VGroup = ReactVTable.Group; const VText = ReactVTable.Text; const VImage = ReactVTable.Image; const VTag = ReactVTable.Tag; const { useCallback, useRef, useState } = React; 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'] } ]; const CustomLayoutComponent = (props) => { const { table, row, col, rect, text } = props; if (!table || row === undefined || col === undefined) { return null; } const { height, width } = rect || table.getCellRect(col, row); const record = table.getRecordByRowCol(col, row); const [hoverTitle, setHoverTitle] = React.useState(false); const [hoverIcon, setHoverIcon] = React.useState(false); const groupRef = React.useRef(null); return ( <VGroup attribute={{ id: 'container', width, height, display: 'flex', flexWrap: 'nowrap', justifyContent: 'flex-start', alignContent: 'center' }} ref={groupRef} > <VGroup attribute={{ id: 'container-left', width: 60, height, fill: 'red', opacity: 0.1, display: 'flex', justifyContent: 'space-around', alignItems: 'center' }} > <VImage attribute={{ id: 'icon0', width: 50, height: 50, image: record.bloggerAvatar, cornerRadius: 25 }} ></VImage> </VGroup> <VGroup id="container-right" attribute={{ id: 'container-right', width: width - 60, height, fill: 'yellow', opacity: 0.1, display: 'flex', flexWrap: 'nowrap', flexDirection: 'column', justifyContent: 'space-around', alignItems: 'center' }} > <VGroup attribute={{ id: 'container-right-top', fill: 'red', opacity: 0.1, width: width - 60, height: height / 2, display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-start', alignItems: 'center' }} > <VText attribute={{ id: 'bloggerName', text: record.bloggerName, fontSize: 13, fontFamily: 'sans-serif', fill: hoverTitle ? 'red' : 'black', textAlign: 'left', textBaseline: 'top', boundsPadding: [0, 0, 0, 10] }} onMouseEnter={(event) => { setHoverTitle(true); event.currentTarget.stage.renderNextFrame(); }} onMouseLeave={(event) => { setHoverTitle(false); event.currentTarget.stage.renderNextFrame(); }} ></VText> <VImage attribute={{ id: 'location-icon', width: 15, height: 15, image: '<svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"><path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"></path><path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"></path><path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"></path></svg>', boundsPadding: [0, 0, 0, 10], cursor: 'pointer', background: hoverIcon ? { fill: '#ccc', cornerRadius: 5, expandX: 1, expandY: 1 } : undefined }} onMouseEnter={event => { setHoverIcon(true); event.currentTarget.stage.renderNextFrame(); }} onMouseLeave={event => { setHoverIcon(false); event.currentTarget.stage.renderNextFrame(); }} ></VImage> <VText attribute={{ id: 'locationName', text: record.city, fontSize: 11, fontFamily: 'sans-serif', fill: '#6f7070', textAlign: 'left', textBaseline: 'top' }} ></VText> </VGroup> <VGroup attribute={{ id: 'container-right-bottom', fill: 'green', opacity: 0.1, width: width - 60, height: height / 2, display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-start', alignItems: 'center' }} > {record.tags.length ? record.tags.map((str, i) => ( // <VText attribute={{ // text: str, // fontSize: 10, // fontFamily: 'sans-serif', // fill: 'rgb(51, 101, 238)', // textAlign: 'left', // textBaseline: 'rop', // boundsPadding: [0, 0, 0, 10], // }}></VText> <VTag key={i} textStyle={{ fontSize: 10, fontFamily: 'sans-serif', fill: 'rgb(51, 101, 238)' // textAlign: 'left', // textBaseline: 'rop', }} panelStyle={{ visible: true, fill: '#e6fffb', lineWidth: 1, cornerRadius: 4 }} boundsPadding={[0, 0, 0, 10]} >{str}</VTag> )) : null} </VGroup> </VGroup> </VGroup> ); } const App = () => { const [columns, setColumns] = React.useState([{ field: 'bloggerName', title: 'bloggerName' },{ field: 'bloggerId', title: 'bloggerId' }]); return ( <div> <button onClick={()=> { setColumns([...columns,...columns]) }}>ceshi</button> <ReactVTable.ListTable records={records} defaultRowHeight={80} height={'500px'} rowSeriesNumber={{ title: '序号', width: 60 }} > {columns.map((item)=> { return (<ReactVTable.ListColumn field={item.field} title={item.title} width={330} disableHover={true}> <CustomLayoutComponent role={'custom-layout'} /> </ReactVTable.ListColumn>) })} </ReactVTable.ListTable> </div> ) } const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID)); root.render( <App/> ); // release openinula instance, do not copy window.customRelease = () => { root.unmount(); };
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: *
@.>

TankTao commented 2 months ago

以前的版本,是不是确实存在这个问题比如1.5.3

---原始邮件--- 发件人: @.> 发送时间: 2024年9月4日(周三) 晚上6:01 收件人: @.>; 抄送: @.**@.>; 主题: Re: [VisActor/VTable] [Bug] react 自定义单元格,动态usestate 设置列的时候,table会报错(在设置行号后会出现,rowSeriesNumber={{ title: '序号', width: 60 }}) (Issue #2375)

20240904180035rec.gif (view on web) 试了一下,最新版是没问题的,可以升级一下版本

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

Rui-Sun commented 2 months ago

这个代码,在你们网页上是执行不了的吧,执行就会报错,识别不了usestate ---原始邮件--- 发件人: @.> 发送时间: 2024年9月4日(周三) 晚上6:02 收件人: @.>; 抄送: @.**@.>; 主题: Re: [VisActor/VTable] [Bug] react 自定义单元格,动态usestate 设置列的时候,table会报错(在设置行号后会出现,rowSeriesNumber={{ title: '序号', width: 60 }}) (Issue #2375) 测试代码 // import * as ReactVTable from @.*/react-vtable'; const VGroup = ReactVTable.Group; const VText = ReactVTable.Text; const VImage = ReactVTable.Image; const VTag = ReactVTable.Tag; const { useCallback, useRef, useState } = React; 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'] } ]; const CustomLayoutComponent = (props) => { const { table, row, col, rect, text } = props; if (!table || row === undefined || col === undefined) { return null; } const { height, width } = rect || table.getCellRect(col, row); const record = table.getRecordByRowCol(col, row); const [hoverTitle, setHoverTitle] = React.useState(false); const [hoverIcon, setHoverIcon] = React.useState(false); const groupRef = React.useRef(null); return ( <VGroup attribute={{ id: 'container', width, height, display: 'flex', flexWrap: 'nowrap', justifyContent: 'flex-start', alignContent: 'center' }} ref={groupRef} > <VGroup attribute={{ id: 'container-left', width: 60, height, fill: 'red', opacity: 0.1, display: 'flex', justifyContent: 'space-around', alignItems: 'center' }} > <VImage attribute={{ id: 'icon0', width: 50, height: 50, image: record.bloggerAvatar, cornerRadius: 25 }} ></VImage> </VGroup> <VGroup id="container-right" attribute={{ id: 'container-right', width: width - 60, height, fill: 'yellow', opacity: 0.1, display: 'flex', flexWrap: 'nowrap', flexDirection: 'column', justifyContent: 'space-around', alignItems: 'center' }} > <VGroup attribute={{ id: 'container-right-top', fill: 'red', opacity: 0.1, width: width - 60, height: height / 2, display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-start', alignItems: 'center' }} > <VText attribute={{ id: 'bloggerName', text: record.bloggerName, fontSize: 13, fontFamily: 'sans-serif', fill: hoverTitle ? 'red' : 'black', textAlign: 'left', textBaseline: 'top', boundsPadding: [0, 0, 0, 10] }} onMouseEnter={(event) => { setHoverTitle(true); event.currentTarget.stage.renderNextFrame(); }} onMouseLeave={(event) => { setHoverTitle(false); event.currentTarget.stage.renderNextFrame(); }} ></VText> <VImage attribute={{ id: 'location-icon', width: 15, height: 15, image: '<svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"><path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"></path><path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"></path><path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"></path></svg>', boundsPadding: [0, 0, 0, 10], cursor: 'pointer', background: hoverIcon ? { fill: '#ccc', cornerRadius: 5, expandX: 1, expandY: 1 } : undefined }} onMouseEnter={event => { setHoverIcon(true); event.currentTarget.stage.renderNextFrame(); }} onMouseLeave={event => { setHoverIcon(false); event.currentTarget.stage.renderNextFrame(); }} ></VImage> <VText attribute={{ id: 'locationName', text: record.city, fontSize: 11, fontFamily: 'sans-serif', fill: '#6f7070', textAlign: 'left', textBaseline: 'top' }} ></VText> </VGroup> <VGroup attribute={{ id: 'container-right-bottom', fill: 'green', opacity: 0.1, width: width - 60, height: height / 2, display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-start', alignItems: 'center' }} > {record.tags.length ? record.tags.map((str, i) => ( // <VText attribute={{ // text: str, // fontSize: 10, // fontFamily: 'sans-serif', // fill: 'rgb(51, 101, 238)', // textAlign: 'left', // textBaseline: 'rop', // boundsPadding: [0, 0, 0, 10], // }}></VText> <VTag key={i} textStyle={{ fontSize: 10, fontFamily: 'sans-serif', fill: 'rgb(51, 101, 238)' // textAlign: 'left', // textBaseline: 'rop', }} panelStyle={{ visible: true, fill: '#e6fffb', lineWidth: 1, cornerRadius: 4 }} boundsPadding={[0, 0, 0, 10]} >{str}</VTag> )) : null} </VGroup> </VGroup> </VGroup> ); } const App = () => { const [columns, setColumns] = React.useState([{ field: 'bloggerName', title: 'bloggerName' },{ field: 'bloggerId', title: 'bloggerId' }]); return ( <div> <button onClick={()=> { setColumns([...columns,...columns]) }}>ceshi</button> <ReactVTable.ListTable records={records} defaultRowHeight={80} height={'500px'} rowSeriesNumber={{ title: '序号', width: 60 }} > {columns.map((item)=> { return (<ReactVTable.ListColumn field={item.field} title={item.title} width={330} disableHover={true}> <CustomLayoutComponent role={'custom-layout'} /> </ReactVTable.ListColumn>) })} </ReactVTable.ListTable> </div> ) } const root = ReactDom.createRoot(document.getElementById(CONTAINER_ID)); root.render( <App/> ); // release openinula instance, do not copy window.customRelease = () => { root.unmount(); }; — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: *@.>

可以用我发的这个,我改了一下;以前的版本有这个问题,已经修复了