Skip to content

自适应性能表格

vue
<template>
	<fk-space direction="vertical">
		<VxeGrid ref="grid" class="config-table" v-bind="gridOptions" v-on="gridEvents" />
	</fk-space>
</template>

<script setup lang="tsx">
import { onMounted, reactive, useTemplateRef } from 'vue';
import { cloneDeep } from 'lodash-es';
import { VxeGrid, mergeGridProps, s8 } from '@erp/biz';
import data from './data.json';
import type { VxeGridInstance, VxeGridListeners } from '@erp/biz';

/**
 * 引用template模板
 */
const gridRef = useTemplateRef<VxeGridInstance>('grid');

/**
 * 表格 grid 配置
 */
const gridOptions = reactive(
	mergeGridProps({
		optimize: true,
		height: 660,
		columnConfig: {
			width: 160,
		},
		radioConfig: {
			trigger: 'row',
			strict: false,
		},
		toolbarConfig: {
			buttons: [
				{
					label: '重新请求数据',
					code: 'getData',
					type: 'primary',
				},
			],
		},
		checkboxConfig: {
			isShiftKey: true,
			range: true,
		},
		showOverflow: false,
		// scrollY: null,
		scrollY: {
			enabled: true,
			gt: 0,
			mode: 'wheel',
			oSize: 6,
			// scrollToTopOnChange: true,
		},
		scrollX: null,
		mouseConfig: {
			area: true,
			selected: true,
		},
		areaConfig: {
			autoClear: true,
			areaStatusTeleportTo: '.vxe-grid--pager-status',
			// 自定义区域状态显示
			formatAreaStatus({ cellAreas }) {
				if (cellAreas[0]) {
					const area = cellAreas[0];
					const sum = area.cols
						.reduce((sum, col) => {
							return (
								sum +
								area.rows.reduce((sum, row) => {
									return sum + (Number(row[col.field]) || 0);
								}, 0)
							);
						}, 0)
						.toFixed(2);
					const count = area.cols.length * area.rows.length;
					const out = [
						{
							label: '单元格',
							value: count,
						},
						{
							label: '求和',
							value: sum,
						},
						{
							label: '平均',
							value: (+sum / count).toFixed(2),
						},
					];
					return out
						.map(item => {
							return `<span style="padding: 0 6px;">${item.label}: ${item.value}</span>`;
						})
						.join(' ');
				} else {
					return '';
				}
			},
		},
		columns: [
			{ type: 'checkbox', width: 55, align: 'center', headerAlign: 'center', fixed: 'left' },
			{ type: 'seq', width: 55, align: 'center', headerAlign: 'center', fixed: 'left' },
			{
				field: 'client_name',
				title: '客户名称',
			},
			{
				field: 'id',
				title: '内部订单号',
			},
			{
				field: 'order_status',
				title: '状态',
				sortable: true,
				filterMultiple: true,
				filters: [
					{ label: '0', value: 0, checked: false },
					{ label: '1', value: 1, checked: false },
					{ label: '2', value: 2, checked: false },
					{ label: '3', value: 3, checked: false },
					{ label: '4', value: 4, checked: false },
					{ label: '5', value: 5, checked: false },
					{ label: '6', value: 6, checked: false },
				],
			},
			{ field: 'payment_fee', title: '已付金额', align: 'right' },
			{
				field: 'order_tags',
				title: '标记',
			},
			{ field: 'order_time', title: '订单日期', width: 170 },
			{ field: 'pay_time', title: '付款时间', width: 170 },
			{ field: 'buyer_account', title: '买家账号+店铺' },
			{ field: 'meet', title: '应付+运费' },
			{ field: 'remaining_amount', title: '剩余支付金额' },

			{ field: 'client_remark', title: '客户留言' },
			{ field: 'customer_notes', title: '卖家备注' },
			{ field: 'offline_remark', title: '线下备注' },
			{ field: 'expresses', title: '快递公司' },
			{ field: 'receiver_address', title: '收货地址' },
			{ field: 'plan_ship_time', title: '计划发货日期' },
			{ field: 'order_sale', title: '业务员' },
			{ field: 'confirm_time', title: '确认收货时间' },
			{ field: 'remaining_delivery_time', title: '剩余发货时间', fixed: 'right' },
			{ field: 'order_source', title: '订单来源', fixed: 'right' },
		],
		data: [],
	}),
);

const init = (length?: number) => {
	gridOptions.loading = true;
	setTimeout(() => {
		let list = cloneDeep(data.data.list)
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.concat(cloneDeep(data.data.list))
			.map(v => {
				const name =
					'阿是斐林试剂反杀款到发货撒沙发偶哦额水电费看后感的刚打开发货的咖啡阿是斐林试剂反杀款到发货撒沙发偶哦额水电费看后感的刚打开发货的咖啡';
				v.buyer_account = name.slice(0, Math.floor(Math.random() * name.length));
				v.client_name = name.slice(0, Math.floor(Math.random() * name.length));
				v.id = s8() as any;
				return v;
			});
		list = list.slice(0, Math.floor(Math.random() * (length || list.length)));
		gridOptions.data = list;
		gridOptions.pagerConfig.total = list.length;
		gridOptions.loading = false;
	}, 1000);
};

const gridEvents: VxeGridListeners = {
	toolbarButtonClick: ({ code, $grid }) => {
		if (code === 'getData') {
			init(1000);
		}
	},
	cellAreaSelectionStart: params => {
		console.log('cellAreaSelectionStart >>', params);
	},
	cellAreaSelectionEnd: params => {
		console.log('cellAreaSelectionEnd >>', params);
	},
	cellAreaSelectionChange: params => {
		console.log('cellAreaSelectionChange >>', params);
	},
	clearCellAreaSelection: params => {
		console.log('clearCellAreaSelection >>', params);
	},
};

onMounted(init);
</script>

基于 MIT 许可发布