需求

合并行、合并标题、列宽可调整、列顺序可调整、可以控制列是否显示、列布局可保存、导出excel…
需求

参考效果

在这里插入图片描述
在这里插入图片描述

代码

引入

npm i xlsx
npm install element-plus --save

table组件



<template>
	<div>
		<div class="table-btn">
			<div class="left-btn">
				<slot name="tableBtn" />
			</div>
			<div class="right-btn">
				<el-tooltip content="高级筛选" placement="bottom" effect="light">
				<el-button :icon="Search" circle @click="dialogRulesVisible = true" />
			</el-tooltip>
			<el-tooltip content="修改table" placement="bottom" effect="light">
				<el-button :icon="EditPen" circle @click="dialogVisible = true" />
			</el-tooltip>
			<el-tooltip content="导出xlsx" placement="bottom" effect="light">
				<el-button :icon="Download" circle @click="exportBtn" />
			</el-tooltip>
			</div>
		</div>

		<el-table @sort-change="sortTableDataChange"
			:data="tableData"
			style="width: 100%"
			ref="exportTableRef"
			border
			v-loading="state.loading"
			:cell-style="tableStyle?.cellStyle"
			:header-cell-style="tableStyle?.headerCellStyle"
		>
			 <template v-for="item in tablePropList">
        <el-table-column
          sortable="custom"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
          :align="item.align"
          :width="item.width == 0 ? '' : item.width"
          :fixed="item.fixed"
          v-if="item.showable && item.children.length > 0"
        >
          <template v-for="itemChildren in item.children">
            <el-table-column
              :key="itemChildren.prop"
              sortable="custom"
              :prop="itemChildren.prop"
              :label="itemChildren.label"
              :align="itemChildren.align"
              :width="itemChildren.width == 0 ? '' : itemChildren.width"
              v-if="itemChildren.showable"
            >
            </el-table-column>
          </template>
        </el-table-column>
        <el-table-column
          sortable="custom"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
          :align="item.align"
          :width="item.width == 0 ? '' : item.width"
          :fixed="item.fixed"
          v-if="item.showable && item.children.length == 0 && !item.isSlot"
        >
          <template #default="scope">
            {{ scope.row[item.prop] }}
          </template>
        </el-table-column>
        <el-table-column
          sortable="custom"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
          :align="item.align"
          :width="item.width == 0 ? '' : item.width"
          :fixed="item.fixed"
          v-if="item.showable && item.children.length == 0 && item.isSlot"
        >
          <template #default="scope">
            <slot :name="item.prop" v-bind="scope" :msg="scope.row[item.prop]" />
            <!-- {{ scope.row[item.prop] }}123 -->
          </template>
        </el-table-column>
      </template>
      <!-- 插槽 -->
      <slot />
		</el-table>

		<el-dialog v-model="dialogVisible" title="自定义布局" width="80%">
			<div class="over-height">
				<el-table :data="tablePropList" style="width: 100%" row-key="prop">
					<el-table-column prop="prop" label="API名"> </el-table-column>
					<el-table-column prop="date" label="列名">
						<template #default="scope">
							<el-input v-model="scope.row.label" />
						</template>
					</el-table-column>
					<el-table-column prop="date" label="序列">
						<template #default="scope">
							<el-input-number v-model="scope.row.index" :min="0" :max="100" />
						</template>
					</el-table-column>
					<el-table-column prop="date" label="宽度(0为自适应)">
						<template #default="scope">
							<el-input v-model="scope.row.width" class="w120" />
						</template>
					</el-table-column>
					<el-table-column prop="date" label="对齐方式">
						<template #default="scope">
							<el-radio-group v-model="scope.row.align">
								<el-radio-button label="left">左对齐</el-radio-button>
								<el-radio-button label="center">居中</el-radio-button>
								<el-radio-button label="right">右对齐</el-radio-button>
							</el-radio-group>
						</template>
					</el-table-column>
					<el-table-column prop="date" label="是否固定">
						<template #default="scope">
							<el-radio-group v-model="scope.row.fixed">
								<el-radio-button label="left" >左侧固定</el-radio-button>
								<el-radio-button label="" >不固定</el-radio-button>
								<el-radio-button label="right" >右侧固定</el-radio-button>
							</el-radio-group>
						</template>
					</el-table-column>
					<el-table-column prop="date" label="是否显示">
						<template #default="scope">
							<el-radio-group v-model="scope.row.showable">
								<el-radio-button :label="true"  >显示</el-radio-button>
								<el-radio-button :label="false" >隐藏</el-radio-button>
							</el-radio-group>
						</template>
					</el-table-column>
				</el-table>
			</div>
			<template #footer>
				<span class="dialog-footer">
					<el-button type="primary" @click="sortTableData(0)">保存并确定</el-button>
					<el-button type="primary" @click="sortTableData(1)">确定</el-button>
				</span>
			</template>
		</el-dialog>

		<el-dialog v-model="dialogRulesVisible" title="高级筛选" width="80%">
			<div class="dialog-header">
				<div>
					<el-button-group class="ml-4">
						<el-button type="primary" plain @click="addRulesTable">新增筛选</el-button>
						<el-button type="primary" plain @click="resetting()">重置条件</el-button>
					</el-button-group>
				</div>
				<div>
					<el-button-group class="ml-4">
						<el-button type="primary" plain @click="rulesTableData(0)">保存方案</el-button>
						<el-button type="primary" plain @click="rulesTableData(2)">另存方案</el-button>
					</el-button-group>

					<el-select v-model="selectRulesCount" @change="rulesSelect()" placeholder="选择方案">
						<el-option v-for="(item, index) in configurationRules" :key="index" :label="item.name" :value="index" />
					</el-select>
				</div>
			</div>

			<div class="over-height">
				<el-table :data="tableRulesList" style="width: 100%" row-key="prop" :tree-props="{ children: 'filters' }">
					<el-table-column prop="field" label="列名">
						<template #default="scope">
							<el-select v-model="scope.row.field" @change="rulesPropsChange(scope.row)">
								<el-option v-for="item in tablePropsList.props" :key="item.prop" :label="item.label" :value="item.prop" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="operator" label="比较运算符">
						<template #default="scope">
							<el-select v-model="scope.row.operator" :disabled="scope.row.field == ''" @change="switchType(scope.row, scope.row.operator)">
								<el-option label="等于" value="eq" v-show="scope.row.type == 'number' || scope.row.type == 'string' || scope.row.type == 'date'" />
								<el-option label="不等于" value="ne" v-show="scope.row.type == 'number' || scope.row.type == 'string' || scope.row.type == 'date'" />
								<el-option label="大于" value="gt" v-show="scope.row.type == 'number' || scope.row.type == 'date'" />
								<el-option label="大于或等于" value="ge" v-show="scope.row.type == 'number' || scope.row.type == 'date'" />
								<el-option label="小于" value="lt" v-show="scope.row.type == 'number' || scope.row.type == 'date'" />
								<el-option label="小于或等于" value="le" v-show="scope.row.type == 'number' || scope.row.type == 'date'" />
								<el-option label="介于" value="between" v-show="scope.row.type == 'date'" />
								<el-option label="不介于" value="notBetween" v-show="scope.row.type == 'date'" />

								<el-option label="包含" value="like" v-show="scope.row.type == 'string'" />
								<el-option label="不包含" value="notLike" v-show="scope.row.type == 'string'" />
								<el-option label="以…开始" value="likeLeft" v-show="scope.row.type == 'string'" />
								<el-option label="以…结束" value="likeRight" v-show="scope.row.type == 'string'" />
								<el-option label="" value="isNull" v-show="scope.row.type == 'string'" />
								<el-option label="非空" value="isNotNUll" v-show="scope.row.type == 'string'" />

								<el-option label="在列表之中" value="in" v-show="scope.row.type == 'number' || scope.row.type == 'string'" />
								<el-option label="不在列表之中" value="notIn" v-show="scope.row.type == 'number' || scope.row.type == 'string'" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="value" label="">
						<template #default="scope">
							<template v-if="scope.row.operator != 'in' && scope.row.operator != 'notIn'">
								<el-input v-if="scope.row.type == 'string'" v-model="scope.row.value" :disabled="scope.row.field == ''" />
								<el-input-number
									v-if="scope.row.type == 'number'"
									v-model="scope.row.value"
									:min="0"
									:max="1000000"
									:disabled="scope.row.field == ''"
								/>
								<el-date-picker
									v-if="
										(scope.row.type == 'date' && scope.row.operator == 'between') || (scope.row.type == 'date' && scope.row.operator == 'notBetween')
									"
									v-model="scope.row.value"
									type="daterange"
									range-separator="To"
									start-placeholder="开始时间"
									end-placeholder="结束时间"
								/>
								<el-date-picker
									v-if="scope.row.type == 'date' && scope.row.operator != 'between' && scope.row.operator != 'notBetween'"
									v-model="scope.row.value"
									type="date"
								/>
							</template>
							<el-select
								multiple
								v-if="
									(scope.row.type == 'number' && scope.row.operator == 'in') ||
									(scope.row.type == 'number' && scope.row.operator == 'notIn') ||
									(scope.row.type == 'string' && scope.row.operator == 'in') ||
									(scope.row.type == 'string' && scope.row.operator == 'notIn')
								"
								v-model="scope.row.value"
							>
								<el-option v-for="item in scope.row.inList" :key="item.value" :label="item.label" :value="item.value" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="logic" label="逻辑运算符">
						<template #default="scope">
							<el-select v-model="scope.row.logic" :disabled="scope.row.field == ''">
								<el-option label="并且" value="and" />
								<el-option label="或者" value="or" />
							</el-select>
						</template>
					</el-table-column>
					<el-table-column prop="value" label="操作">
						<template #default="scope">
							<el-tooltip content="嵌套过滤条件" placement="bottom" effect="light">
								<el-button type="primary" plain :icon="Plus" @click="addchildrenTable(scope.row)"></el-button>
							</el-tooltip>
							<el-tooltip content="移除当前筛选" placement="bottom" effect="light">
								<el-button type="primary" plain :icon="Minus" @click.prevent="deleteRow(scope.$index, scope.row)"></el-button>
							</el-tooltip>
						</template>
					</el-table-column>
				</el-table>
			</div>

			<template #footer>
				<span class="dialog-footer">
					<el-button type="primary" @click="rulesTableData(1)">确定</el-button>
				</span>
			</template>
		</el-dialog>

		<el-dialog v-model="dialogFormVisible" title="请为该规则添加一个名字">
			<el-input v-model="ruleName" autocomplete="off" />
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="dialogFormVisible = false">取消</el-button>
					<el-button type="primary" @click="addRulesName">确定</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script lang="ts" setup>
// npm i xlsx
// npm install element-plus --save
import { EditPen, Download, Search, Close, Plus, Minus } from '@element-plus/icons-vue';
import { ref } from 'vue';
import { toRefs, defineProps, defineEmits } from 'vue';
import { BasicTableProps, useTable } from '/@/hooks/table';
const emit = defineEmits(['tableRules']);

// 弹窗布尔值
const dialogVisible = ref(false);
const dialogRulesVisible = ref(false);

// 接收值
const props = defineProps({
	//子组件接收父组件传递过来的值
	tableData: Array,
	tablePropsList: Object,
});
//使用父组件传递过来的值
const { tableData, tablePropsList } = toRefs(props);

const state: BasicTableProps = reactive<BasicTableProps>({});
//  表单的配置项,根据回传的数据判断是否用哪个值
const { getDataList, currentChangeHandle, sizeChangeHandle, downBlobFile, tableStyle } = useTable(tablePropsList.value.state ?? state);

// 获取当前页的配置表
const localTable = JSON.parse(localStorage.getItem('table'));

const configuration = ref([]);

const configurationRules = ref([]);

if (localTable && localTable[tablePropsList.value.id]) {
	configuration.value = localTable[tablePropsList.value.id].configuration;
	configurationRules.value = localTable[tablePropsList.value.id].rules;
} else {
	// 没有的话就新建一个保存
	let obj = {
		[tablePropsList.value.id]: {
			configuration: [],
			rules: [],
		},
	};
	localStorage.setItem('table', JSON.stringify(obj));
}

const tablePropList = ref([]);
// 处理数据(原始传入数据,本地存储的数据,导出的数据)
const switchTableData = (tableData, localStorageData, addData) => {
	// prop: 表格绑定字段, label:当前名, index:表格当前序列,width:表格当前宽度,align: 对齐方式 left左 center中 right右,showable:是否显示 true显示,false隐藏
	tableData.forEach((e, index) => {
		if (localStorageData && localStorageData.length > 0) {
			localStorageData.forEach((ec) => {
				if (ec.prop == e.prop) {
					let obj = {
						prop: ec.prop,
						label: ec.label,
						index: ec.index,
						width: ec.width,
						showable: ec.showable,
						inList: ec.inList ? ec.inList : null,
						align: ec.align,
						fixed: ec.fixed,
						children: [],
						rules: ec.rules,
						type: ec.type,
						filterable: ec.filterable,
            isSlot: ec.isSlot,
					};
					addData.push(obj);
					if (e.children) {
						switchTableData(e.children, ec.children, obj.children);
					}
				}
			});
		} else {
			let obj = {
				prop: e.prop,
				label: e.label,
				index: index,
				width: e.width ? e.width : 0,
				showable: e.showable ? e.showable : true,
				inList: e.inList ? e.inList : null,
				align: e.align ? e.align : 'center',
				fixed: e.fixed ? e.fixed : false,
				children: [],
				rules: {},
				type: e.type ? e.type : 'string',
				filterable: e.filterable ? e.filterable : false,
        isSlot: e.isSlot ? e.isSlot : false,
			};
			addData.push(obj);
			if (e.children) {
				switchTableData(e.children, null, obj.children);
			}
		}
	});
};

switchTableData(tablePropsList.value.props, configuration.value, tablePropList.value);

// 给数组排序
const sortTableData = (type) => {
	// type 0 保存并确定 1 确定
	tablePropList.value.sort(function (a, b) {
		return a.index - b.index; // 根据升序排序
	});
	dialogVisible.value = false;
	if (type == 0) {
		let arr = JSON.parse(localStorage.getItem('table')) || {};
		arr[tablePropsList.value.id].configuration = tablePropList.value;
		localStorage.setItem('table', JSON.stringify(arr));
	}
};

// 选中缓存的规则
const selectRulesItem = ref({
	name: '',
	rules: [],
});
// 选中缓存的规则
const selectRulesCount = ref();
const rulesSelect = (val) => {
	tableRulesList.value = configurationRules.value[selectRulesCount.value].rules;
	selectRulesItem.value = configurationRules.value[selectRulesCount.value];
};

const dialogFormVisible = ref(false);
const tableRulesList = ref([]);
// 数据添加筛选规则
const rulesTableData = (type) => {
	// type 0 保存并确定 1 确定 2 新建
	dialogRulesVisible.value = false;
	let rulesList = {
		logic: 'and',
		field: '',
		operator: '',
		value: '',
		sort: [sortTableDataSort.value],
		filters: {},
	};
	rulesList.filters = tableRulesList.value;
	// tablePropList.value.forEach((e) => {
	// 	rulesList.sort.push({
	// 		field: e.prop,
	// 		dir: e.index,
	// 	});
	// });
	if (type == 2) {
		dialogFormVisible.value = true;
	}
	if (type == 0) {
		if (selectRulesItem.value.name) {
			configurationRules.value[selectRulesCount.value].rules = tableRulesList.value;
			let arr = JSON.parse(localStorage.getItem('table')) || {};
			arr[tablePropsList.value.id].rules = configurationRules.value;
			localStorage.setItem('table', JSON.stringify(arr));
			setTimeout(() => {
				let localTable = JSON.parse(localStorage.getItem('table'));
				configuration.value = localTable[tablePropsList.value.id].configuration;
				configurationRules.value = localTable[tablePropsList.value.id].rules;
			}, 100);
		} else {
			dialogFormVisible.value = true;
		}
	}
	//传递给父组件
	emit('tableRules', rulesList);
};
const sortTableDataSort = ref({
	field: '',
	dir: 'asc',
})
const sortTableDataChange = (column, prop, order) => {
  sortTableDataSort.value.field = column.prop
  sortTableDataSort.value.dir = column.order=="ascending"?'asc':'desc'
  rulesTableData(1)
}

import { ElMessage } from 'element-plus';
const ruleName = ref('');
const addRulesName = () => {
	let filteredNumbers = configurationRules.value.filter((ev) => ev.name == ruleName.value);
	if (filteredNumbers.length == 0) {
		let obj = {
			name: ruleName.value,
			rules: tableRulesList.value,
		};
		configurationRules.value.push(obj);
		let arr = JSON.parse(localStorage.getItem('table')) || {};
		arr[tablePropsList.value.id].rules = configurationRules.value;
		localStorage.setItem('table', JSON.stringify(arr));
		dialogFormVisible.value = false;

		setTimeout(() => {
			let localTable = JSON.parse(localStorage.getItem('table'));
			configuration.value = localTable[tablePropsList.value.id].configuration;
			configurationRules.value = localTable[tablePropsList.value.id].rules;
		}, 100);
	} else {
		ElMessage({
			message: '重名,请换个名称',
			type: 'warning',
		});
	}
};

const addRulesTable = (type) => {
	tableRulesList.value.push({
		logic: 'and',
		field: '',
		operator: '',
		value: '',
		fieldCount: tableRulesList.value.length * Math.floor(Math.random() * 10000),
	});
};

const rulesPropsChange = (item) => {
	let filteredNumbers = tablePropsList.value.props.filter((ev) => ev.prop == item.field);
	item.label = filteredNumbers[0].label;
	item.prop = filteredNumbers[0].prop;
	item.type = filteredNumbers[0].type;
	item.filterable = filteredNumbers[0].filterable;
	item.showable = filteredNumbers[0].showable;
	item.inList = filteredNumbers[0].inList;
	item.value = '';
	item.operator = '';
	switchType(item, item.type);
};

// 新增子项筛选
const addchildrenTable = (item) => {
	if (item.hasChildren == null) {
		if (!item.filters) {
			item.filters = new Array();
		}
		item.filters.push({
			logic: 'and',
			field: '',
			operator: '',
			value: '',
			hasChildren: item.fieldCount, // 是否是子项数据 ,以及是哪一条的子项数据
			fieldCount: tableRulesList.value.length * Math.floor(Math.random() * 10000),
		});
	} else {
		tableRulesList.value.forEach((e) => {
			if (e.fieldCount == item.hasChildren) {
				e.filters.push({
					logic: 'and',
					field: '',
					operator: '',
					value: '',
					hasChildren: e.fieldCount, // 是否是子项数据 ,以及是哪一条的子项数据
					fieldCount: tableRulesList.value.length * Math.floor(Math.random() * 10000),
				});
			}
		});
	}
};

const deleteRow = (index, item) => {
	if (item.hasChildren != null) {
		tableRulesList.value.forEach((e) => {
			if (e.fieldCount == item.hasChildren) {
				e.filters = e.filters.filter((es) => es.fieldCount != item.fieldCount);
			}
		});
	}
	if (item.hasChildren == null) {
		tableRulesList.value = tableRulesList.value.filter((e) => e.fieldCount != item.fieldCount);
	}
};

const resetting = () => {
	tableRulesList.value = [];
};

const switchType = (row, type) => {
	if (type == 'between' || type == 'notBetween' || type == 'array') {
		row.value = new Array();
	}
	if (type == 'string') {
		row.value = new String();
	}
	if (type == 'number') {
		row.value = new Number();
	}
};

// 导出功能
import * as XLSX from 'xlsx';
const exportTableRef = ref(null);
const exportBtn = () => {
	const tableDom = exportTableRef.value?.$el;
	if (!tableDom) {
		return;
	}

	const wb = XLSX.utils.table_to_book(tableDom);
	XLSX.writeFile(wb, tablePropsList.value.exportXlsxName ?? '表格数据.xlsx');
};
</script>


<style scoped>
.over-height {
	max-height: 60vh;
	overflow-y: auto;
}
.el-select {
	width: 120px;
}

.el-input {
	width: 200px;
}
.w120 {
	width: 120px;
}

.table-btn {
	display: flex;
	justify-content: space-between;
	margin-bottom: 2px;
}
.last-table {
	width: 94%;
	margin: 0 auto;
}
.dialog-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
}
</style>



demo

<template>
  <div>
    <h2>直接使用</h2>
    <!-- 
      tableData 是渲染表单的原始数据,
      tablePropsList是表单的规则数据,
      tableRules 是表单返回的筛选数据,数据在tableRules(val)方法中取返回值 val
      -->
    <tableVue
      :tableData="tableData"
      :tablePropsList="tablePropsList"
      @tableRules="tableRules"
    />

    <h2>添加操作等栏目</h2>
    <tableVue :tableData="tableData" :tablePropsList="tablePropsList">
      
			<!-- 顶部增加按钮 -->
			<template #tableBtn>
				<el-button>123</el-button>
				<el-button>123</el-button>
				<el-button>123</el-button>
			</template>
			<!-- 该组件可继续添加表格数据 -->
			<!-- 如果需要增加操作栏列等,可以按照以下格式添加 -->
			<el-table-column fixed="right" label="Operations" width="120">
				<template #default="scope">
					<el-button link type="primary" size="small"> Remove{{ scope.$index }} </el-button>
				</template>
			</el-table-column>
    </tableVue>
  </div>
</template>
<script setup>
import { ref } from "vue";
import tableVue from "./components/table.vue";
// 定义的数据
const tableData = ref([
  {
    id:1,
    date: "2016-05-03",
    name: "Aom1",
    address: "No. 189, Grove St, Los Angeles",
    count: 1,
    address3: "address3",
    address4: "address4",
  },
  {
    id:2,
    date: "2016-05-02",
    name: "BTom2",
    address: "No. 189, Grove St, Los Angeles",
    count: 1,
    address3: "address3",
    address4: "address4",
  },
  {
    id:3,
    date: "2016-05-04",
    name: "CTom",
    address: "No. 189, Grove St, Los Angeles",
    count: 1,
    address3: "address3",
    address4: "address4",
  },
  {
    id:4,
    date: "2016-05-01",
    name: "DTom",
    address: "No. 189, Grove St, Los Angeles",
    count: 1,
    address3: "address3",
    address4: "address4",
  },
]);

// 需要定义关键字和关键字的label
const tablePropsList = ref({
	// id 唯一值,必填
	id: 'text-table',
	// 导出表格的文件名,非必填
	exportXlsxName: 'xlsx-table',
	// 非必填,表单的配置项
	state: state,
	/**
	 * 必填项
	 * label为表格名
	 * prop对应表格的参数
	 *
	 * 选填
	 * width 表格宽度,0自适应,可填数字,默认自适应
	 * showable 是否显示 0 显示,1不显示,默认0
	 * align 对其方式 left 左对齐, center居中对其,right:右对齐,默认center
	 * fixed 是否固定 left 固定左侧,right 固定右侧,空值不固定,默认空
	 * type 数据类型,默认为空
	 * filterable 是否可筛选 默认true
	 * inList 当该属性的 operator 值可能为 in/notIn 时,可以通过配置 inList 来为其增加筛选项,不配置默认为null,并且 operator 值为 in/notIn 时,选择器无选项
	 */
	props: [
		{
			label: '姓名',
			prop: 'name',
			type: 'string',
			filterable: true,
			showable: true,
		},
		{
			label: '时间',
			prop: 'date',
			type: 'date',
			filterable: true,
			showable: true,
		},
		{
			label: '地址',
			prop: 'address',
			type: 'string',
			filterable: true,
			showable: true,
			inList: [
				{
					value: 1,
					label: '草稿',
				},
				{
					value: 2,
					label: '审批中',
				},
				{
					value: 3,
					label: '已完成',
				},
			],
		},
		{
			label: '数量',
			prop: 'count',
			type: 'number',
			filterable: true,
			showable: true,
		},
		{
			label: '状态',
			prop: 'count',
			type: 'number',
			filterable: true,
			showable: true,
			isSlot: true,
		},
		{
			label: '其他地址',
			prop: 'address2',
			showable: true,
			// children 为子数据
			children: [
				{
					label: '地址3',
					prop: 'address3',
					type: 'string',
					filterable: true,
					showable: true,
				},
				{
					label: '地址4',
					prop: 'address4',
					type: 'string',
					filterable: false,
					showable: true,
				},
			],
		},
	],
});
// 接收子组件返回的筛选规则
const tableRules = (val) => {
	console.log('rules', val);
};
</script>


<style scoped>
</style>


GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:1 个月前 )
c345bb45 5 个月前
a07f3a59 * Update transition.md * Update table.md * Update transition.md * Update table.md * Update transition.md * Update table.md * Update table.md * Update transition.md * Update popover.md 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐