赞
踩
// tableBox.vue <template> <div class="table-c"> <a-table :expandIcon="customIcon" :columns="tableColumns" :data-source="dataSource" :pagination="pagination" :loading="loading" :rowSelection="rowSelection" @change="change" @expand="expand" > <template v-for="i in tableColumns" :key="i.key" v-slot:[i.slots?.customRender]="{ record }" > <slot :name="i.slots?.customRender" :record="record"></slot> </template> <template v-slot:[expandedRowRender]="{ record }"> <slot name="expandedRowRender" :record="record"></slot> </template> </a-table> <a-modal title="列表设置" v-model:visible="visible" :width="800" :confirmLoading="tableHeadLoading" :bodyStyle="{ paddingBottom: '10px', }" > <a-checkbox-group v-model:value="tableHead" class="checked-item"> <a-row> <a-col :span="5" v-for="check in columns" :key="check.key" :offset="1" > <a-checkbox :value="check.key" :disabled="check.key == 'action'"> <span v-text="check.key == 'action' ? '操作' : check.title" ></span> </a-checkbox> </a-col> </a-row> </a-checkbox-group> <template #footer> <div class="pop-btn-box"> <div class="btn-left"> <a-button @click="checkAll">全选</a-button> <a-button @click="checkNoAll">全不选</a-button> </div> <div class="btn-right"> <a-button @click="handleHeadCancel">返回</a-button> <a-button type="primary" @click="setConfirm" class="ok-btn" >确定</a-button > </div> </div> </template> </a-modal> </div> </template> <script setup> import { h, reactive, ref } from "vue"; import { RightOutlined, SettingOutlined } from "@ant-design/icons-vue"; import { message } from "ant-design-vue"; import { useStore } from "vuex"; const store = useStore(); const props = defineProps({ columns: { // 弹窗显示的所有项 type: Array, default: [], }, pagination: { type: Object, default: { hideOnSinglePage: true, }, }, rowSelection: { type: Object, default: undefined, }, dataSource: { type: Array, default: [], }, expandedRowRender: { type: String, default: "", }, routerName: { type: String, default: "", }, loading:{ type:Boolean, default:false } }); let tableColumns = ref([]); let visible = ref(false); let tableHead = ref([]); let initTabHead = []; const tableHeadLoading = ref(false); const attrsName = ref(""); attrsName.value = props.routerName; const emit = defineEmits(["change", "expand"]); //构造表格列 const createColumns = () => { const arr = props.columns.map((item) => { let obj = { ...item }; obj.isShow = item.isShow != undefined ? item.isShow : true; obj.dataIndex = item.key; !obj.slots && item.isSlot ? (obj.slots = { customRender: item.key }) : ""; item.key === "action" ? (obj.title = h(SettingOutlined, { class: "set-icon", onClick: () => { visible.value = true; }, })) : ""; return obj; }); initTabHead = [...arr]; // 用于后续操作 tableHead.value = arr // 控制全选以及选中的项 .filter((i) => { if (i.isShow) { return i; } }) .map((t) => t.key); return arr; }; let showColumns = createColumns(); showColumns = showColumns.filter((i) => i.isShow == true); tableColumns.value = showColumns; // 表格显示的所有项,isShow 为true时 const checkAll = () => { let showArr = []; initTabHead.forEach((tab) => { tab.isShow = true; showArr.push(tab); }); tableHead.value = showArr .filter((i) => { if (i.isShow) { return i; } }) .map((t) => t.key); }; const checkNoAll = () => { let showArr = []; initTabHead.forEach((tab) => { tab.isShow = false; if (tab.key == "action") { tab.isShow = true; showArr.push(tab); } }); tableHead.value = showArr .filter((i) => { if (i.isShow) { return i; } }) .map((t) => t.key); }; //设置显示那些列 const setConfirm = () => { tableHeadLoading.value = true; let showArr = []; let setArr = []; initTabHead.forEach((tab) => { tab.isShow = false; tableHead.value.forEach((el) => { if (tab.key == el) { tab.isShow = true; showArr.push(tab); setArr.push(el); } }); }); tableHeadLoading.value = false; if (showArr.length < 2) { message.info("至少选中两项"); } else { tableColumns.value = showArr; let obj = Object.assign({}, store.state.tableHeadObj); obj[attrsName.value] = [...setArr]; store.commit("setTableHeadObj", obj); message.success("设置成功"); visible.value = false; } }; const handleHeadCancel = () => { createColumns(); // 重置 visible.value = false; }; //分页改变事件 const change = (pagination, filters, sorter) => { emit("change", { pagination, filters, sorter }); }; const expand = (expanded, record) => { emit("expand", { expanded, record }); }; //自定义展开图标 const customIcon = (arg) => { if ( arg.record.children?.length || props.expandedRowRender == "expandedRowRender" ) { return h(RightOutlined, { class: arg.record.key + "expand", style: { transition: "all 0.3s", cursor: "pointer", padding: "5px" }, onclick: async (e) => { let dom = document.getElementsByClassName(arg.record.key + "expand")[0]; arg.expanded ? (dom.style.cssText = "transform:rotateZ(0)") : (dom.style.cssText = "transform:rotateZ(90deg)"); arg.onExpand(arg.record, e); }, }); } else { return h("span", { style: { display: "inline-block", with: "14px" } }); } }; </script> <style lang="less" scoped> .table-c { margin-top: 0.08rem; } .checked-item { margin-left: -24px; } .ant-checkbox-group { width: 100%; } .ant-checkbox-wrapper { padding: 2px 8px; margin-bottom: 0.1rem; border-radius: 4px; white-space: nowrap; width: 100%; &:hover { background: @table-head-set-bg; } } .ant-checkbox-wrapper-checked { background: @table-head-set-bg; } .pop-btn-box { display: flex; justify-content: space-between; .btn-right { .ok-btn { color: @btn-primary-color; } } } </style>
import { createApp } from 'vue'; import App from './App.vue'; import router from './router/index.js'; import store from './store'; import { changeSize } from './utils/common.js'; import antd from 'ant-design-vue'; import tableBox from "@/components/tableBox.vue"; import 'ant-design-vue/dist/antd.less'; import './assets/common/style.less'; import 'nprogress/nprogress.css' changeSize() const app = createApp(App) app.component('table-box', tableBox); app.use(antd).use(router).use(store).mount('#app')
// index.vue <table-box v-if="isShow" :columns="state.columns" :dataSource="state.tableData" :pagination="pagination" :rowSelection="rowSelection" @change="handleTableChange" :routerName="routerName" > <template v-slot:expandedRowRender="{ record }"> <span>{{ record }}</span> </template> <template #action="{ record }"> <a-popover title=""> <template #content> <div class="action-box" style="display: flex; flex-direction: column" > <a @click="handleEdit(true, record)">修改</a> <a @click="handleDel(record.id)" href="javascript:void(0)" >删除</a > </div> </template> <MenuOutlined /> </a-popover> </template> </table-box> <script setup> import { useRoute } from "vue-router"; const route = useRoute(); const routerName = ref(route.name); const isShow = ref(false); const expandedRowRender = ref("expandedRowRender"); const state = reactive({ tableData: [], columns: [ { title: "厂商名称", key: "firmName", dataIndex: "firmName", ellipsis: true, }, { title: "简称", key: "abbreviation", dataIndex: "abbreviation", ellipsis: true, }, { title: "地址", key: "address", dataIndex: "address", ellipsis: true, }, { title: "联系人", key: "liaison", dataIndex: "liaison", }, { title: "联系电话", key: "liaisonPhone", dataIndex: "liaisonPhone", ellipsis: true, }, { key: "action", isSlot: true, slots: { customRender: "action", }, }, ], selectedRowKeys: [], }); const getTableData = (formData) => { for (let i = 0; i < 12; i++) { state.tableData.push({ id: i, key: i, firmName: "江苏汇水创", abbreviation: "汇水创", address: "高塘石", liaison: "陈辉", liaisonPhone: "1371507698", }); } }; const rowSelection = { onChange: (selectedRowKeys, selectedRows) => { state.selectedRowKeys = selectedRowKeys; console.log( `selectedRowKeys: ${selectedRowKeys}`, "selectedRows: ", selectedRows ); }, }; // 切换页 const handleTableChange = (page, filters, sorter) => { pagination.current = page.current; pagination.pageSize = page?.pageSize; // console.log(filters); // 选中值为数组(单选直接拿第一项,多选把数组转化成字符串拼接 - 看后台需要什么数据结构) if (filters.type) { // 必须判断,未操作切换页会报错(无type属性) formData.type = filters.type[0]; } getTableData(formData); }; onMounted(async () => { // 判断是否已经设置过表头,有则使用 if ( sessionStorage.tableHeadObj && JSON.parse(sessionStorage.tableHeadObj)[routerName.value] ) { let arr = JSON.parse(sessionStorage.tableHeadObj)[routerName.value]; for (let i = 0; i < state.columns.length; i++) { if (arr.indexOf(state.columns[i].key) == -1) { state.columns[i].isShow = false; } } isShow.value = true; } else { isShow.value = true; } getTableData(formData); }); </script>
// store.js
import {
createStore
} from "vuex";
export default createStore({
state: {
tableHeadObj: sessionStorage.tableHeadObj ? JSON.parse(sessionStorage.tableHeadObj): {}
},
mutations: {
setTableHeadObj(state, obj) {
state.tableHeadObj = obj;
sessionStorage.tableHeadObj = JSON.stringify(state.tableHeadObj);
}
}
})
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。