当前位置: 首页 > news >正文

vue实现antd-vue table表格 右上角设置列功能(支持列搜索列、上移、下移、置顶、置底)

根据现有需求考虑到表头很多,写了组件弹窗支持列搜索列、上移、下移、置顶、置底,上代码:

子组件:

<a-modal v-model:visible="visible" title="列设置" width="600px" @ok="handleOk" @cancel="handleCancel"><!-- 选项卡:全部列、显示列、隐藏列 --><a-tabs v-model:activeKey="activeTab" @change="changeTabCallback"><a-tab-pane key="all" tab="全部列"><a-table:data-source="filteredData":columns="columnsList":pagination="false":row-selection="{ selectedRowKeys: selectedColumns, onChange: colChange }"><template #headerCell="{ column }"><template v-if="column.key === 'title'"><span style="color: #1890ff">名称 {{ selectedColumns.length }}/{{ filteredData.length }}</span></template></template><template #customFilterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }"><div style="padding: 8px"><a-inputref="searchInput":placeholder="`搜索${column.title}`":value="selectedKeys[0]"style="width: 188px; margin-bottom: 8px; display: block"@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"@pressEnter="handleSearch(selectedKeys, confirm, column.dataIndex)"/><a-buttontype="primary"size="small"style="width: 90px; margin-right: 8px"@click="handleSearch(selectedKeys, confirm, column.dataIndex)"><template #icon><SearchOutlined /></template>Search</a-button><a-button size="small" style="width: 90px" @click="handleReset(clearFilters)"> Reset </a-button></div></template><template #customFilterIcon="{ filtered }"><search-outlined :style="{ color: filtered ? '#1890ff' : '#1890ff' }" /></template><template #bodyCell="{ record, column, index }"><span v-if="searchText && searchedColumn === column.dataIndex"><template v-for="(fragment, i) in record.title.toString().split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))"><mark v-if="fragment.toLowerCase() === searchText.toLowerCase()" :key="i" class="highlight">{{ fragment }}</mark><template v-else>{{ fragment }}</template></template></span><template v-if="column.dataIndex === 'action'"><a-space><a @click="moveItem(record, index, 'up')">上移</a><a-divider type="vertical" /></a-space><a-space><a @click="moveItem(record, index, 'down')">下移</a><a-divider type="vertical" /></a-space><a-space><a @click="moveItem(record, index, 'top')">置顶</a><a-divider type="vertical" /></a-space><a-space><a @click="moveItem(record, index, 'bottom')">置底</a><a-divider type="vertical" /></a-space></template></template></a-table></a-tab-pane><a-tab-pane key="visible" tab="显示列"><a-list><a-list-item v-for="col in visibleColumns" :key="col.key">{{ col.title }}</a-list-item></a-list></a-tab-pane><a-tab-pane key="hidden" tab="隐藏列"><a-list><a-list-item v-for="col in hiddenColumns" :key="col.key">{{ col.title }}</a-list-item></a-list></a-tab-pane></a-tabs></a-modal>

  

<script>
export default {props: {visible: Boolean,columns: Array // 所有列配置
  },emits: ['update:visible', 'change'],data() {return {searchedColumn: '',searchText: '', // 搜索文本activeTab: 'all', // 当前选项卡(all/visible/hidden)selectedColumns: [], // 当前选中的列(存储 col.key)
      selectedRowKeys: [],filteredData: [],columnsList: [{title: '名称',dataIndex: 'title',key: 'title',width: 260,minWidth: 260,customFilterDropdown: true,onFilter: (value, record) => record.title.toString().toLowerCase().includes(value.toLowerCase()),onFilterDropdownOpenChange: visible => {if (visible) {setTimeout(() => {searchInput.value.focus();}, 100);}}},{title: '操作',dataIndex: 'action'}]};},computed: {// 显示的列(当前选中的列)
    visibleColumns() {return this.columns.filter(col => this.selectedColumns.includes(col.key));},// 隐藏的列
    hiddenColumns() {return this.columns.filter(col => !this.selectedColumns.includes(col.key));}},watch: {// 监听初始化
    visible() {if (this.visible) {this.searchText = '';this.filteredData = [...this.columns];this.selectedColumns = this.columns.filter(col => col.checked) // 初始选中的列(如果 col 有 checked 属性).map(col => col.key);}}},methods: {changeTabCallback(key) {if (key == 'visible') {}},colChange(val, key) {this.selectedColumns = val;this.filteredData = this.updateCheckedStatus(this.filteredData, val);},updateCheckedStatus(data, targetKeys) {return data.map(column => ({...column, // 保留原有属性checked: targetKeys.includes(column.key) // 如果 key 在 targetKeys 中,则 checked: true,否则 false
      }));},handleOk() {this.selectedColumns = this.filteredData.filter(item => item.checked) // 筛选 checked: true 的项.map(item => item.key); // 提取 keythis.$emit('change', this.selectedColumns, this.filteredData);this.$emit('update:visible', false);},handleCancel() {this.$emit('update:visible', false);},moveItem(record, index, type) {const arr = this.filteredData;if (type === 'up' && index > 0) {[arr[index - 1], arr[index]] = [arr[index], arr[index - 1]];}if (type === 'down' && index < arr.length - 1) {[arr[index + 1], arr[index]] = [arr[index], arr[index + 1]];}if (type === 'top' && index > 0) {const item = arr.splice(index, 1)[0];arr.unshift(item);}if (type === 'bottom' && index < arr.length - 1) {const item = arr.splice(index, 1)[0];arr.push(item);}// 带有fixed: right属性始终在最下面arr.sort((a, b) => {const aHasFixed = a.fixed === 'right';const bHasFixed = b.fixed === 'right';if (aHasFixed && !bHasFixed) return 1; // a 带 fixed,b 不带,a 排后面if (!aHasFixed && bHasFixed) return -1; // a 不带 fixed,b 带,a 排前面return 0; // 保持原有顺序
      });},handleSearch(selectedKeys, confirm, dataIndex) {confirm();this.searchText = selectedKeys[0];this.searchedColumn = dataIndex;},handleReset(clearFilters) {clearFilters({confirm: true});this.searchText = '';}}
};
</script>

父组件:

<a-tooltip placement="top"><template #title><span>列设置</span></template><SettingOutlined @click="showColumnSettings" /></a-tooltip><columnSettings v-model:visible="columnSettingsVisible" :columns="columns" @change="handleColumnsChange" />
export default {data() {
return: {
columnSettingsVisible: false,// 表格列配置
      columns: [{key: 'index',width: 48,checked: true,hideInSetting: true,customRender: ({index}) => this.$refs.table.tableIndex + index},{title: '订单号',dataIndex: 'orderMovementXid',key: 'orderMovementXid',checked: true,resizable: true,width: 160,minWidth: 100},{title: '创建日期',dataIndex: 'orderCreationDate',key: 'orderCreationDate',checked: true,resizable: true,width: 160,minWidth: 100},{title: '金额',dataIndex: 'contractAmountInc',key: 'contractAmountInc',checked: true,resizable: true,width: 160,minWidth: 100},{title: '名称',dataIndex: 'templateName',key: 'templateName',checked: true,resizable: true,width: 160,minWidth: 100},{title: '明细',dataIndex: 'templateDetailCode',key: 'templateDetailCode',checked: true,resizable: true,width: 160,minWidth: 100},{title: '状态',dataIndex: 'chargingStatus',key: 'chargingStatus',checked: true,resizable: true,width: 160,minWidth: 100},{title: '原因',dataIndex: 'chargingFailReason',key: 'chargingFailReason',checked: true,resizable: true,width: 160,minWidth: 100},{title: '操作',key: 'action',checked: true,width: 120,align: 'center',fixed: 'right'}],
}
},methods: {showColumnSettings() {this.columnSettingsVisible = true;},handleColumnsChange(selectedKeys, filteredData) {// 更新列的显示状态this.columns = filteredData;},
},
 computed: {
    displayedColumns() {
      return this.columns.filter(col => col.checked);
    }
  }
}

展示效果

image

 

http://www.sczhlp.com/news/80265/

相关文章:

  • 企业网站建设相关书籍2020新闻大事件摘抄
  • 韶关网站seo做化工哪个网站好
  • 成品网站w灬源码999交友学校官网入口
  • 哪些网站可以做免费推广广州市绿色建筑信息平台
  • 网页设计公司网站wordpress数据库没有填写
  • 北京城建设计集团网站网站建设中源码编程同样重要
  • 高密市建设局网站广州软件制作公司
  • 自己做网站宣传产品网站开发范例文档
  • 商品网站怎么做校园网站建设的请示
  • 网站管理人员队伍建设有待加强包装设计效果图生成器
  • vivado2024,vitis Embedded点击没反应
  • 基于MountainTop数据的STAP算法仿真实现
  • 40、合同落款内容右移
  • 第四届公共管理、数字经济与互联网技术国际学术会议(ICPDI 2025)
  • 旅游网站设计报告网站自然排名怎么做
  • 网站基础建设巴巴商友圈门户网站建设管理
  • 网站建设公司利润常州建站服务
  • 酒店网站设计的目的和意义做电信网站运营
  • 盘锦市建设银行网站python自学网
  • 西安网站建设那家好新能源电动汽车价格
  • 建设银行行号网站查询是什么意思建立微信群怎么建
  • ui培训设计机构靖江seo收费贵吗
  • 专门做设计文案的网站iis 建设网站
  • 芜湖网站建设全包仅需800元网站的建设及维护的费用
  • 怎样建设企业网站 用于宣传中山外发加工网
  • 想要个网站网站建设汕头
  • 四平做网站网页设计师制作培训
  • 途牛的旅游网站是谁做的做机械的外贸网站
  • 企业网站设计请示网页界面设计体会
  • 网站建设怎么分录WordPress哪些主题是免费的