Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

虚拟表格 #6814

Open
3 tasks done
likeeprunning opened this issue Mar 21, 2025 · 5 comments
Open
3 tasks done

虚拟表格 #6814

likeeprunning opened this issue Mar 21, 2025 · 5 comments
Labels
feature request New feature or request

Comments

@likeeprunning
Copy link

Clear and concise description of the problem

n-data-table设置了虚拟滚动 如果render函数里渲染的是比较复杂的组件的时候 拖拽滚动条滚动还是非常卡顿

Suggested solution

希望增加一个虚拟表格的组件

Alternative

No response

Additional context

No response

Validations

  • Read the Contributing Guidelines.
  • Read the docs.
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
@likeeprunning likeeprunning added the feature request New feature or request label Mar 21, 2025
@Rolaka
Copy link

Rolaka commented Mar 25, 2025

https://www.naiveui.com/zh-CN/os-theme/components/data-table#virtual.vue

尝试使用 virtual-scroll、virtual-scroll-x 开启虚拟列表支持?

@likeeprunning
Copy link
Author

likeeprunning commented Mar 25, 2025

https://www.naiveui.com/zh-CN/os-theme/components/data-table#virtual.vue

尝试使用 virtual-scroll、virtual-scroll-x 开启虚拟列表支持?

所有的配置已经配置过了 用的官方的例子 只不过把render函数里渲染的组件比较复杂 拖动横向滚动条的时候很卡

@Rolaka
Copy link

Rolaka commented Mar 25, 2025

https://www.naiveui.com/zh-CN/os-theme/components/data-table#virtual.vue
尝试使用 virtual-scroll、virtual-scroll-x 开启虚拟列表支持?

所有的配置已经配置过了 用的官方的例子 只不过把render函数里渲染的组件比较复杂 拖动横向滚动条的时候很卡

首先,开启virtual-scroll、virtual-scroll-x 之后,他的渲染方式已经是虚拟列表模式了,性能是可以的,详见:
https://github.com/tusen-ai/naive-ui/blob/main/src/data-table/src/TableParts/Body.tsx
你可以在render 函数里面打日志观察渲染范围。

其次,没有demo 就没法判断性能瓶颈在哪里,到底是单个render 计算或者dom 结构太复杂,还是过度使用的过渡或者css 样式,还是虚拟列表的问题,还是单纯的数据量太大,这没法判断。

@likeeprunning
Copy link
Author

likeeprunning commented Mar 25, 2025

https://www.naiveui.com/zh-CN/os-theme/components/data-table#virtual.vue
尝试使用 virtual-scroll、virtual-scroll-x 开启虚拟列表支持?

所有的配置已经配置过了 用的官方的例子 只不过把render函数里渲染的组件比较复杂 拖动横向滚动条的时候很卡

首先,开启virtual-scroll、virtual-scroll-x 之后,他的渲染方式已经是虚拟列表模式了,性能是可以的,详见: https://github.com/tusen-ai/naive-ui/blob/main/src/data-table/src/TableParts/Body.tsx 你可以在render 函数里面打日志观察渲染范围。

其次,没有demo 就没法判断性能瓶颈在哪里,到底是单个render 计算或者dom 结构太复杂,还是过度使用的过渡或者css 样式,还是虚拟列表的问题,还是单纯的数据量太大,这没法判断。

demo如下:
template部分

<n-form
	ref="formRef"
	:model="formData"
	:show-feedback="false"
>
  <n-data-table
  	:loading="loading"
  	class="h-full"
  	flex-height
  	:columns="columns"
  	:data="formData.tableData"
  	:scrollX="scrollX"
  	virtual-scroll
  	virtual-scroll-x
  	:min-row-height="58"
  	:header-height="58"
  	:height-for-row="heightForRow"
  	:scrollbar-props="scrollBarProps"
  	ref="tableRef"
  ></n-data-table>
</n-form>

js部分

const renderFormItem = (
	componentName,
	rowData,
	rowIndex,
	prop,
	options,
	isNeedPopConfirm = false
) => {
return h(
NFormItem,
{
	label: '',
	showLabel: false,
	path: options?.rule ? `tableData[${rowIndex}].${prop}` : undefined,
	rule: options?.rule || undefined
},
[renderPopOver(componentName, rowData, prop, options, isNeedPopConfirm)]
)
}
const renderPopOver = (
	componentName,
	rowData,
	prop,
	options,
	isNeedPopConfirm
) => {
	const _renderButtonSlot = () => {
		return h(
			NButton,
			{
				text: true,
				type: 'primary',
				onClick: isNeedPopConfirm
					? null
					: withModifiers(() => {
							if (options.handleClick) {
								options.handleClick()
							} else {
								updateColumnData(prop, rowData[prop])
							}
					  }, ['stop'])
			},
			'应用全部'
		)
	}
	const _renderDefaultSlot = () => {
		if (isNeedPopConfirm) {
			return h(
				NPopconfirm,
				{
					onPositiveClick: withModifiers(() => {
						updateColumnData(prop, rowData[prop])
					}, ['stop']),
					width: 200,
					...options
				},
				{
					trigger: _renderButtonSlot(),
					default: options.confirmTitle || '确认?'
				}
			)
		} else {
			return _renderButtonSlot()
		}
	}
	const _renderTriggerSlot = () => {
		return h(componentName, {
			value: rowData[prop],
			onUpdateValue(value) {
				if (value === null) {
					rowData[prop] = ''
					return
				}
				rowData[prop] = value
			},
			...options
		})
	}
	return h(
		NPopover,
		{
			trigger: 'hover',
			class:
				(rowData[prop] || rowData[prop] === 0) && !options.disabled
					? 'block'
					: 'hidden'
		},
		{
			default: _renderDefaultSlot(),
			trigger: _renderTriggerSlot()
		}
	)
}
for (let i = 0; i < 1000; ++i) {
  scrollX += 100
  columns.push({
    title: `Col ${i}`,
    width: 100,
    key: i,
    fixed: i <= 1 ? 'left' : i > 997 ? 'right' : undefined,
    render(rowData, rowIndex) {
        const config = {
        	clearable: true,
        	rule: {
        		required: true,
        		message: `请输入${key}`,
        		trigger: 'blur'
        	}
        }
    return renderFormItem(NInput, rowData, rowIndex, i , config)
    }
  })
}

@Rolaka
Copy link

Rolaka commented Mar 26, 2025

https://www.naiveui.com/zh-CN/os-theme/components/data-table#virtual.vue
尝试使用 virtual-scroll、virtual-scroll-x 开启虚拟列表支持?

所有的配置已经配置过了 用的官方的例子 只不过把render函数里渲染的组件比较复杂 拖动横向滚动条的时候很卡

首先,开启virtual-scroll、virtual-scroll-x 之后,他的渲染方式已经是虚拟列表模式了,性能是可以的,详见: https://github.com/tusen-ai/naive-ui/blob/main/src/data-table/src/TableParts/Body.tsx 你可以在render 函数里面打日志观察渲染范围。
其次,没有demo 就没法判断性能瓶颈在哪里,到底是单个render 计算或者dom 结构太复杂,还是过度使用的过渡或者css 样式,还是虚拟列表的问题,还是单纯的数据量太大,这没法判断。

demo如下: template部分

随便补了点代码测试了下,这写法卡顿很正常吧?

  1. 拖拽卡一个是虚拟列表的渲染策略问题,在正常滚动的时候会有一些屏外余量,但直接拖拽就是整屏渲染。
  2. 另一个是无意义渲染的问题,单算表格尺寸500px,一屏幕就是80个元素,即使换了别的虚拟表格组件也有性能问题。

实测 (demo,仅演示,交互应该是有问题的) 可以参照”可切换的可编辑表格“,交互后才切换到编辑模式,不触发则直接渲染字符串,可以大幅提升性能。如果需求上需要看起来是个输入框,那CSS 做个外观上的操作吧。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants