Skip to content

表头自定义过滤器

  1. 配置表头自定义过滤器
vue
<template>
	<VxeGrid ref="grid" class="config-table" v-bind="gridOptions" v-on="gridEvents" />
</template>

<script setup lang="tsx">
import { onMounted, reactive, useTemplateRef } from 'vue';
import { Input, VxeGrid, mergeGridProps } from '@erp/biz';
import { dayjs } from '@erp/common';
import data from './data.json';
import type { VxeGridInstance, VxeGridListeners } from '@erp/biz';

/**
 * 引用template模板
 */
const gridRef = useTemplateRef<VxeGridInstance>('grid');
const options = [];
/**
 * 表格 grid 配置
 */
const gridOptions = reactive(
	mergeGridProps({
		optimize: 'sticky',
		height: 360,
		columnConfig: {
			width: 160,
		},
		filterConfig: {
			// remote:
			autoFocus: true,
			// teleportTo: '.VPPage',
		},
		pagerConfig: {
			slots: {
				center() {
					return (
						<div>
							自定义状态栏:<span style="color: red;">444</span>
						</div>
					);
				},
			},
		},
		scrollX: null,
		toolbarConfig: {
			buttons: [
				{
					label: '清除筛选条件',
					code: 'clearFilter',
					type: 'primary',
				},
			],
		},
		columns: [
			{ field: 'checkbox', type: 'checkbox', width: 55, align: 'center', headerAlign: 'center', fixed: 'left' },
			{
				type: 'seq',
				title: '#',
				width: 55,
				align: 'center',
				headerAlign: 'center',
				fixed: 'left',
			},
			{
				field: 'order_status',
				title: '状态',
				width: 220,
				filters: [],
				filterRender: {
					name: 'Input',
					props: {
						type: 'cascader',
						multiple: true,
						triggerProps: { composite: true },
						options: [
							{
								value: 'beijing',
								label: 'Beijing',
								children: [
									{
										value: 'chaoyang',
										label: 'ChaoYang',
										children: [
											{
												value: 'datunli',
												label: 'Datunli',
											},
										],
									},
									{
										value: 'haidian',
										label: 'Haidian',
									},
									{
										value: 'dongcheng',
										label: 'Dongcheng',
									},
									{
										value: 'xicheng',
										label: 'Xicheng',
										children: [
											{
												value: 'jinrongjie',
												label: 'Jinrongjie',
											},
											{
												value: 'tianqiao',
												label: 'Tianqiao',
											},
										],
									},
								],
							},
							{
								value: 'shanghai',
								label: 'Shanghai',
								children: [
									{
										value: 'huangpu',
										label: 'Huangpu',
									},
								],
							},
						],
					},
				},
			},
			{
				title: '综合信息',
				align: 'center',
				headerAlign: 'center',
				children: [
					{
						field: 'xid',
						title: '内部订单号',
						sortable: true,
						filters: [],
						width: 200,
						slots: {
							header() {
								return (
									<span>
										<fk-tag size="mini" color="fkblue" bordered>
											T+1
										</fk-tag>
										内部订单号
									</span>
								);
							},
							filter({ column, model }) {
								return (
									<Input
										type="user-tree-select"
										modelValue={model[column.field]}
										onUpdate:modelValue={value => {
											model[column.field] = value;
										}}
										options={column.filters}
										triggerProps={{ composite: true }}
									></Input>
								);
							},
						},
						filterMethod({ row, value }) {
							if (value) {
								return row.id == value;
							}
							return true;
						},
						formatter(params) {
							return params.row.id;
						},
					},
					{
						field: 'id',
						title: '标记',
						filters: [],
						filterRender: {
							name: 'Input',
							props: {
								type: 'select',
								multiple: true,
								triggerProps: { composite: true },
							},
						},
					},
					{
						field: 'payment_fee',
						title: '已付金额',
						filters: [],
						filterRender: {
							name: 'Input',
							compareOperator: 'between',
							props: {
								type: 'range-number',
								precision: 2,
								placeholder: ['最低', '最高'],
								hideButton: true,
							},
						},
					},
				],
			},
			{
				field: 'buyer_account',
				title: '买家账号+店铺',
				filters: [],
				filterRender: {
					name: 'Input',
					compareOperator: 'include',
					props: {
						type: 'text',
					},
				},
			},
			{
				field: 'order_time',
				title: '订单日期',
				width: 260,
				filters: [],
				filterRender: {
					name: 'Input',
					compareOperator: 'between',
					props: {
						type: 'date',
						triggerProps: { composite: true },
					},
				},
				filterMethod({ cellValue, value }) {
					if (value[0] && value[1]) {
						return dayjs(cellValue).isBetween(value[0], value[1]);
					} else if (value[0]) {
						return dayjs(cellValue).isAfter(value[0]);
					} else if (value[1]) {
						return dayjs(cellValue).isBefore(value[1]);
					}
					return true;
				},
			},
			{
				field: 'order_tags',
				title: '标记',
			},
			{ field: 'pay_time', title: '付款时间', width: 170 },
			{ 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: '剩余发货时间' },
			{ field: 'order_source', title: '订单来源' },
		],
		data: [],
	}),
);

/**
 * 监听 grid 事件
 */
const gridEvents: VxeGridListeners = {
	filterChange(params) {
		console.log('filterChange', params);
	},
	pageChange({ pageSize, current }) {
		gridOptions.pagerConfig!.current = current;
		gridOptions.pagerConfig!.pageSize = pageSize;
		handlePageData();
		console.log('pageChange >>', pageSize, current);
	},
	toolbarButtonClick(event) {
		if (event.code === 'clearFilter') {
			gridRef.value?.clearFilter();
		}
	},
	toolbarToolClick(event) {
		console.log('toolbarFoolClick >>', event);
	},
	currentChange(event) {
		console.log('currentChange >>', event);
	},
	menuClick(event) {
		console.log('menuClick >>', event);
	},
	copy(event) {
		// console.log('event >>', event);
		// debugger;
		// clipboard(JSON.stringify(event.row));
	},
	sortChange(params) {
		console.log('sortChange >>', params);
	},
};

const handlePageData = () => {
	gridOptions.loading = true;
	setTimeout(() => {
		const list = data.data.list;
		gridOptions.data = list;
		gridOptions.loading = false;
		gridOptions.pagerConfig!.total = data.data.total;
		list.forEach(el => {
			options.push({
				label: String(el.id),
				value: el.id,
			});
		});
		/**
		 * 设置数据源
		 */
		gridRef.value.setFilter('id', options);
		gridRef.value.setFilter('xid', options);
		// selectProps.options = options;
	}, 500);
};

onMounted(() => {
	handlePageData();
});
</script>

<style scoped lang="less">
.config-table {
	:deep(ul) {
		padding: 0;
		margin: 0;
	}
	:deep(.cell-btns) {
		button + button {
			margin-left: -12px;
		}
	}
	:deep(.vxe-table--filter-template) {
		--width: 240px;
		min-width: var(--width) !important;
		z-index: 999999;
		width: fit-content;
		.fk-select-view-multiple {
			width: var(--width);
		}
		.fk-select-view-single {
			width: var(--width);
		}
		.range-number {
			width: var(--width);
		}
		.fk-picker {
			width: 420px;
		}
		.fk-select-view {
			max-width: 420px;
		}
		.fk-select-dropdown {
			border: none;
			box-shadow: none;
		}
		.fk-cascader-panel {
			border: none;
			box-shadow: none;
		}
		.fk-tree-select-popup {
			border: none;
			box-shadow: none;
		}
		.fk-tree-node {
			max-width: var(--width);
		}
		.fk-trigger-popup-composite {
			margin-top: 6px;
		}
		.fk-cascader-panel-footer {
			position: absolute;
			z-index: 999;
			bottom: 0;
			border-top: none;
			display: inline-flex;
		}
		.fk-select-option {
			max-width: var(--width);
		}
		.fk-cascader-panel-body {
			min-width: var(--width);
			.fk-cascader-panel-column {
				width: 100%;
			}
		}
		.fk-virtual-list {
			max-height: 260px !important;
			padding: 0;
		}
		.fk-cascader-column-wrapper {
			padding: 0;
		}
	}
}
</style>

基于 MIT 许可发布