1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > antdv table组件封装成全局组件以及携带自定义表头展示

antdv table组件封装成全局组件以及携带自定义表头展示

时间:2021-09-14 13:08:19

相关推荐

antdv table组件封装成全局组件以及携带自定义表头展示

1、封装table组件

// 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"><templatev-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-modaltitle="列表设置"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'"><spanv-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];mit("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>

2、在main.js中把组件全局上

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)ponent('table-box', tableBox);app.use(antd).use(router).use(store).mount('#app')

3、在组件中的使用, 因为父子组件的生命周期的原因,所以使用v-if控制子组件的渲染

// index.vue<table-boxv-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><divclass="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>

4、表头数据vuex + sessionStorage (key为路由的名称 – 唯一性)

// store.jsimport {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);}}})

5、效果:

后来者居上:脾气都给了前者,耐心都给了后者

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。