
arcoapi意义:
- dataIndex:列信息的标识,对应TableData中的数据,也就是表头。
- rowKey:表格行key的取值字段,相当于vue中的key绑定的信息。
- columns:表格的列描述信息。
- data:表格的数据。
- column-resizable:是否允许调整列宽。
- select:点击行选择器时触发。
- select-all:点击全选时触发。
- selected:已选择的行。
- selectedRowKeys:已选择的行。
- tooltip:是否在显示省略号时显示文字提示。
- render:自定义列单元格的渲染。
- slotName:设置当前列的渲染插槽的名字。
笔记:
- $attrs号称捡漏王
当父组件给子组件传值,子组件并没有接收数据时,此时数据在$attrs中可以拿到,并且如果子组件不需要使用数组,而孙组件需要,则可以直接v-bind=”$attrs” 传给孙。 - $slots是组件插槽集,是组件所有默认插槽、具名插槽的集合,可以用来获取当前组件的插槽集。
- 可编辑表格:可以在使用插槽获得的数据,修改data中的数据,达到编辑表格的作用,可以直接修改插槽传出的record变量。这个变量是传入的data中对应数据的引用,请保证data为Reactive类型。

<template><div class="main-table-wrapper"><!--如果需要过滤表头就显示下拉框勾选显示的字段--><div class="editor-show-columns-btn" v-if="Props.isShowFliter"><a-dropdown position="br"><a-button><template #icon><icon-settings /></template></a-button><template #content><a-checkbox-group direction="vertical" v-model="selectShowColumns" class="editor-show-columns-ckb"><template v-for="item in showCheckboxColumns" :key="item.dataIndex"><!--展示表格头的title--><a-checkbox v-if="item.isShowFliter !== false" :value="item.dataIndex">{{ item.title }}</a-checkbox></template></a-checkbox-group></template></a-dropdown></div><!--表格体--><a-tableref="TableRef":row-key="Props.rowKey":data="showData":columns="showColumns":column-resizable="true"@select="handleSelected"@selectAll="handleSelectedAll"v-model:selectedKeys="selectedRowKeys"v-bind="$attrs"><!--$slots是组件插槽集,是组件所有默认插槽、具名插槽的集合,可以用来获取当前组件的插槽集。--><template v-for="(s, slot, index) in $slots" :key="index" #[slot]="item"><template v-if="slot === 'customTitle'"><div v-if="isShowCustomColumnTitle" class="custom-title"><slot v-if="isShowCustomColumnTitle" name="customTitle" :item="item"></slot></div><span v-else>{{ customTitleName }}</span></template><!--渲染每一个插槽--><slot v-else :name="slot" :item="item"></slot></template></a-table></div></template><script setup lang="ts">import { useElementSize } from '@vueuse/core'import { computed, ref, watch } from 'vue'import type { TableColumnData, TableData } from '@arco-design/web-vue'import { isEmpty } from 'lodash'const TableRef = ref(null)const box = ref<string>('40px')const { height } = useElementSize(TableRef)const customTitleName = ref<string>('')const showColumns = ref<Array<TableColumnData>>([])const selectedKeysCache = ref<Map<string, any>>(new Map())const Props = withDefaults(defineProps<{rowKey?: stringcolumns: Array<TableColumnData>columnsAll?: Array<TableColumnData>selectedRowKeys?: Array<string>data?: Array<TableData>isShowFliter?: boolean}>(),{rowKey: 'key',columns: () => [] as Array<TableColumnData>,selectedRowKeys: () => [],data: () => [],isShowFliter: false})// 表格的表头,由父组件传的props.columns或columnsAll传递过来const showCheckboxColumns = ref<Array<TableColumnData>>(Props.columnsAll ?? Props.columns)// 过滤之后显示的表头const selectShowColumns = ref<Array<string>>(showCheckboxColumns.value.map((item) => item.dataIndex) as Array<string>)watch(() => Props.columnsAll,(columnsAll) => {if (columnsAll) {showCheckboxColumns.value = columnsAllselectShowColumns.value = showCheckboxColumns.value.map((item) => item.dataIndex) as Array<string>}})/*** 表格展示数据*/const showData = computed(() => {return isEmpty(selectShowColumns.value) ? [] : Props.data})interface IEmitType {(e: 'changeColumns', obj: { columns: Array<TableColumnData>; dataIndexs: Array<string> }): void(e: 'update:columns', columns: Array<TableColumnData>): void(e: 'update:selectedRowKeys', selectedRowKeys: Array<string>): void(e: 'update:selectedRows', selectedRowKeys: Array<TableData>): void(e: 'select', _1: Array<string>, _2: string, _3: TableData, _4: Array<TableData>): void(e: 'selectAll', isAll: boolean): void}const Emits = defineEmits<IEmitType>()const isShowCustomColumnTitle = computed(() => {const targetSelectedRowKeys = Props?.selectedRowKeysif (targetSelectedRowKeys) {return targetSelectedRowKeys.length > 0}return false})/*** 选择一行*/const handleSelected = (_1: Array<string>, rowKey: string, _3: TableData) => {const isExistence = selectedKeysCache.value.has(rowKey)selectedKeysCache.value[isExistence ? 'delete' : 'set'](rowKey, _3)Emits('update:selectedRowKeys', Array.from(selectedKeysCache.value.keys()))Emits('update:selectedRows', Array.from(selectedKeysCache.value.values()))Emits('select',Array.from(selectedKeysCache.value.keys()),rowKey,_3,Array.from(selectedKeysCache.value.values()))}/*** 维护 a-table 自身的 selectedRowKeys*/const selectedRowKeys = ref<string[]>()watch(() => Props.selectedRowKeys,(newVal) => {selectedRowKeys.value = newVal// selectedKeysCache.value.clear()// newVal.map((v) =>// selectedKeysCache.value.set(// v,// Props.data.find((item) => item[Props.rowKey] === v)// )// )},{ immediate: true })/*** 全选*/const handleSelectedAll = (isAll) => {// isAll// ? Props.data?.forEach((item) => selectedKeysCache.value.add(item[Props.rowKey as string]))// : selectedKeysCache.value.clear()if (!isAll) {Props.data.map((item) => selectedKeysCache.value.delete(item[Props.rowKey as string]))} else {Props.data.map((item) => selectedKeysCache.value.set(item[Props.rowKey as string], item))}Emits('update:selectedRowKeys', Array.from(selectedKeysCache.value.keys()))Emits('update:selectedRows', Array.from(selectedKeysCache.value.values()))Emits('selectAll', isAll)}watch(() => Props.columns,(newColumns) => {const targetIndex = newColumns.findIndex((item) => item.customTitle)const targetColumns = [...newColumns]customTitleName.value = (targetColumns[targetIndex]?.title ?? '') as stringtargetColumns[targetIndex] = {...targetColumns[targetIndex],titleSlotName: 'customTitle'}showColumns.value = targetColumnsif (!Props.isShowFliter) {showCheckboxColumns.value = newColumnsselectShowColumns.value = showCheckboxColumns.value.map((item) => item.dataIndex) as Array<string>}},{immediate: true})/*** 更新 columns*/watch(selectShowColumns, (newSelectShowColumns) => {const targetColumns = showCheckboxColumns.value.filter((item) => newSelectShowColumns.includes(item?.dataIndex ?? '') || item.isShowFliter === false)Emits('update:columns', targetColumns)Emits('changeColumns', { columns: targetColumns, dataIndexs: newSelectShowColumns })})/*** 列设置动态大小*/watch(height, () => {const TABLE_TR = document.querySelector('.main-table-wrapper thead .arco-table-tr') as HTMLElementbox.value = TABLE_TR?.offsetHeight ? TABLE_TR?.offsetHeight - 1 + 'px' : box.value})/*** 暴露给外部的state*/const clearSelectedKeysCache = () => selectedKeysCache.value.clear()defineExpose({clearSelectedKeysCache})</script><style lang="scss" scoped>.main-table-wrapper {position: relative;.editor-show-columns-btn {position: absolute;top: 0px;right: 0px;z-index: 1;display: flex;justify-content: center;align-items: center;width: v-bind(box);height: v-bind(box);font-size: 15px;border: 1px solid #e5e6eb;background-color: #f2f3f5;}.custom-title {display: flex;position: absolute;top: 4px;min-height: 24px;z-index: 1;border-radius: 2px;width: max-content;background: #fff;padding: 2px 4px;box-shadow: 0 0 2px 0 rgb(31 31 31 / 5%), 0 4px 6px 0 rgb(31 31 31 / 20%);.forbidden {cursor: not-allowed;}}}.editor-show-columns-ckb {margin: 0 4px;}</style>
