From cd24c776d772c7ad797891afd779b3b072293ec2 Mon Sep 17 00:00:00 2001 From: zrlibs <jesting_rr@163.com> Date: 星期五, 21 三月 2025 17:35:07 +0800 Subject: [PATCH] fixed --- src/components/examples/data-table.vue | 414 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 392 insertions(+), 22 deletions(-) diff --git a/src/components/examples/data-table.vue b/src/components/examples/data-table.vue index d2db141..e9e2ca6 100644 --- a/src/components/examples/data-table.vue +++ b/src/components/examples/data-table.vue @@ -1,19 +1,196 @@ <template> - <div class="data-table"> + <div class="data-table" ref="refDataTable"> + <div v-if="showForm" class="forms" :class="{ collapse: !formExpand }"> + <Form :model="form" v-bind="formObject.options" ref="refForm"> + <Row> + <Col + v-for="(col, index) in formList" + :key="`${index}`" + :span="col.span" + > + <FormItem :label="`${col.label}`"> + <Input + v-if="col.type == 'input'" + v-model="form[col.field]" + size="small" + > + <template v-if="col.suffix" #suffix> + <Icon :type="col.suffix" @click="col.onSuffixClick" /> + </template> + </Input> + <DatePicker + v-else-if="col.type == 'daterange'" + type="daterange" + v-model="form[col.field]" + separator=" 鑷�" + size="small" + style="width: 100%" + @on-change="col.onChange" + ></DatePicker> + <DatePicker + v-else-if="col.type == 'date'" + type="date" + v-model="form[field]" + size="small" + @on-change="col.onChange" + /> + <Select + v-else-if="col.type == 'select'" + v-model="form[col.field]" + size="small" + > + <Option + v-for="(opt, i) in col.options" + :key="i" + :value="col.value" + >{{ col.label }}</Option + > + </Select> + <Checkbox + v-else-if="col.type == 'checkbox'" + v-model="form[col.field]" + size="small" + >{{ form.label }}</Checkbox + > + </FormItem> + </Col> + </Row> + </Form> + <div class="btns"> + <Button type="primary" size="small" + ><Icon type="md-settings" @click="onShowFormDialog" + /></Button> + <Button + v-if="formExpand" + v-show="showFormExpand" + type="primary" + size="small" + @click="formExpand = !formExpand" + ><Icon type="ios-arrow-up" + /></Button> + <Button + v-else + v-show="showFormExpand" + type="primary" + size="small" + @click="formExpand = !formExpand" + ><Icon type="ios-arrow-down" + /></Button> + </div> + </div> + <div class="buttons" v-if="showTopButtons"> + <Space> + <Button + v-for="(btn, i) in buttons" + :key="i" + type="primary" + size="small" + @click="btn.onClick" + >{{ btn.showName }}</Button + > + </Space> + <Space class="ivu-fr"> + <Poptip title="鍒嗛〉鍣ㄤ綅缃� placement="left-start"> + <Tooltip content="璁剧疆鍒嗛〉鍣ㄤ綅缃� transfer> + <Button size="small"><Icon type="md-apps" /></Button> + </Tooltip> + <template #content> + <RadioGroup + v-model="paganationPlacement" + @on-change="onPaganationPlacementChange" + > + <Radio label="top"> + <Icon type="md-at"></Icon> + <span>涓�/span> + </Radio> + <Radio label="bottom"> + <Icon type="md-basketball"></Icon> + <span>涓�/span> + </Radio> + </RadioGroup> + </template> + </Poptip> + <Poptip popper-class="col-list" placement="left-start"> + <Tooltip content="璋冩暣鍒� transfer> + <Button size="small"><Icon type="md-settings" /></Button> + </Tooltip> + <template #title> + <Checkbox + :indeterminate="columnListIndeterminate" + :model-value="columnCheckAll" + @click.prevent="onColumnCheckAll" + >鍏ㄩ�</Checkbox + > + </template> + <template #content> + <CheckboxGroup + v-model="columnShowList" + @on-change="onShowColumnChange" + > + <Checkbox v-for="(col, i) in columns" :key="i" :label="col.key">{{ + toColumnLabel(col) + }}</Checkbox> + </CheckboxGroup> + </template> + </Poptip> + <Poptip title="璁剧疆瀛椾綋澶у皬" placement="left-start"> + <Tooltip content="璋冩暣瀛椾綋" transfer> + <Button size="small"><Icon type="md-apps" /></Button> + </Tooltip> + <template #content> + <RadioGroup v-model="fontSize"> + <Radio label="small"> + <Icon type="md-at"></Icon> + <span>灏�/span> + </Radio> + <Radio label="default"> + <Icon type="md-basketball"></Icon> + <span>涓�/span> + </Radio> + <Radio label="large"> + <Icon type="ios-briefcase"></Icon> + <span>澶�/span> + </Radio> + </RadioGroup> + </template> + </Poptip> + <Tooltip content="鎵撳嵃" transfer> + <Button size="small"><Icon type="ios-print" /></Button> + </Tooltip> + </Space> + <Page + v-if="paged && paganationPlacement == 'top'" + class="absolute" + :model-value="page" + :total="total" + :page-size="limit" + :page-size-opts="limits" + show-sizer + show-total + show-elevator + transfer + simple + @on-change="onPageChange" + @on-page-size-change="onPageSizeChange" + @on-prev="onPrev" + @on-next="onNext" + /> + </div> <Table - class="ivu-table-mini" - :row-class-name="() => ['no-wrap', 'col-gap-none']" - :columns="columns" + class="col-gap-none" + :row-class-name="() => ['no-wrap']" + :columns="tableColumns" :data="data" - :height="paged ? tableHeight - 70 : tableHeight" - border + :height="tableHeight" :highlight-row="highlightRow" + :size="fontSize" + @on-row-click="onRowClick" @on-current-change="onCurrentChange" @on-selection-change="onSelectionChange" ref="refTable" ></Table> <Page - v-if="paged" + v-if="paged && paganationPlacement == 'bottom'" class="text-center" :model-value="page" :total="total" @@ -30,50 +207,173 @@ ref="refPage" /> <Spin fix :show="loading" /> + <FormDialog + v-model="formDialogVisible" + :list="formObject.items" + @ok="onFormDialogOK" + ></FormDialog> </div> </template> <script> import { ref } from "vue"; +import FormDialog from "./form-dialog.vue"; export default { name: "DataTable", + components: { + FormDialog, + }, props: { - tableHeight: Number | String, + // 瀹瑰櫒楂樺害 + height: Number | String, + // 甯歌椤堕儴鎸夐挳 + buttons: { + type: Array, + default: () => [], + }, + // 鏄惁鍒嗛〉 paged: { type: Boolean, default: () => true, }, + // 鍒楀畾涔� columns: { type: Array, default: () => [], }, + // 鏁版嵁婧� data: { type: Array, default: () => [], }, + // 鏁版嵁鎬绘暟 total: { type: Number, default: () => 0, }, + // 褰撳墠椤� page: { type: Number, default: () => 1, }, + // 姣忛〉鍑犳潯鏁版嵁 limit: { type: Number, default: () => 10, }, + // limit鍒楄〃 limits: { type: Array, default: () => [10, 20, 30, 40], }, + // 璁板綍鍔犺浇鐘舵� loading: Boolean, + // 鍗曢�妯″紡 highlightRow: Boolean, + showForm: { + type: Boolean, + default: () => true, + }, + showTopButtons: { + type: Boolean, + default: () => true, + }, + size: { + type: String, + default: () => "default", + }, + pagePlacement: { + type: String, + default: () => "bottom", // top/bottom + }, + formObject: { + type: Object, + default: () => ({}), + }, }, data() { - return {}; + return { + // 閰嶇疆鍝簺鍒楁樉绀�+ columnListIndeterminate: false, + columnCheckAll: true, + columnShowList: [], + // 閰嶇疆瀛椾綋 + fontSize: this.size, + // 鏌ヨ琛ㄥ崟 + // 鏌ヨ琛ㄥ崟鐨勫畾涔�+ form: {}, + formExpand: false, + showFormExpand: true, + formDialogVisible: false, + formShowList: [], + paganationPlacement: this.pagePlacement, + }; + }, + computed: { + // 鏁版嵁鍒楄〃楂樺害 + tableHeight() { + let formHeight = this.showForm + ? this.refDataTable?.querySelector(".forms")?.clientHeight + 9 + : 0; + let buttonHeight = this.showTopButtons + ? this.refDataTable?.querySelector(".buttons")?.clientHeight + : 0; + let pageHeight = + this.paged && this.paganationPlacement == "bottom" ? 70 - 18 : 0; + return this.height - formHeight - buttonHeight - pageHeight; + }, + // 瀹為檯瑕佹樉绀虹殑鍒�+ tableColumns() { + return this.columns.filter((col) => + this.columnShowList.includes(col.key) + ); + }, + // 瀹為檯瑕佹樉绀虹殑琛ㄥ崟椤�+ formList() { + return ( + this.formObject.items?.filter((l) => + this.formShowList.includes(l.field) + ) || [] + ); + }, }, methods: { + toColumnLabel(col) { + if (col.key == "index") return "搴忓彿"; + else if (col.key == "row_button") return "鎿嶄綔鎸夐挳"; + else return col.title; + }, + onPaganationPlacementChange() { + this.$nextTick(() => this.resize()); + }, + // 閰嶇疆鍒�鍏ㄩ� + onColumnCheckAll() { + if (this.columnListIndeterminate) { + this.columnCheckAll = false; + } else { + this.columnCheckAll = !this.columnCheckAll; + } + this.columnListIndeterminate = false; + + if (this.columnCheckAll) { + this.columnShowList = this.columns.map((c) => c.key); + } else { + this.columnShowList = []; + } + }, + // 閰嶇疆鍒�鍗曢� + onShowColumnChange(data) { + if (data.length == this.columns.length) { + this.columnListIndeterminate = false; + this.columnCheckAll = true; + } else if (data.length > 0) { + this.columnListIndeterminate = true; + this.columnCheckAll = false; + } else { + this.columnListIndeterminate = false; + this.columnCheckAll = false; + } + }, onPageChange(page) { this.$emit("on-change", page); }, @@ -100,17 +400,8 @@ onCurrentChange(currentRow) { this.$emit("on-current-change", currentRow); }, - onRowClick(row, index, emit = true) { - this.clickedRowIndex = index; - this.onCurrentChange(row); - if (emit) this.$emit("on-row-click", row, index); - }, - onCellClick(row, column, data, event) { - event.stopPropagation(); - let index = row._index; - if (index === undefined) index = this.rows.find((r) => r.id == row.id); - if (column.key == "row_button") this.onRowClick(row, index, false); - else this.onRowClick(row, index, true); + onRowClick(row, index) { + this.$emit("on-row-click", row, index); }, onSelect(selection, row) { this.$emit("on-select", selection, row); @@ -127,21 +418,100 @@ onColumnWidthResize(newWidth, oldWidth, column, event) { this.$emit("on-column-width-resize", newWidth, oldWidth, column, event); }, + onShowFormDialog() { + this.formDialogVisible = true; + }, + resize() { + this.$nextTick(() => { + let height = this.refForm?.$el?.clientHeight; + if (height < 50) { + this.formExpand = false; + this.showFormExpand = false; + } else { + this.formExpand = true; + this.showFormExpand = true; + } + }); + }, + onFormDialogOK(showList) { + this.formShowList = showList; + }, }, setup() { + const refDataTable = ref(null); + const refForm = ref(null); const refTable = ref(null); const refPage = ref(null); - return { refTable, refPage }; + return { refDataTable, refForm, refTable, refPage }; + }, + watch: { + columns(columns) { + this.columnShowList = columns.map((c) => c.key); + }, + ["formObject.items"](list) { + this.formShowList = list.map((l) => l.field); + }, + formShowList() { + this.resize(); + }, }, }; </script> -<style lang="less" scoped> +<style lang="less"> .data-table { height: 100%; position: relative; + .forms { + margin-bottom: 9px; + padding: 0 10px; + position: relative; + &.collapse { + height: 30px; + padding-right: 100px; + overflow: hidden; + } + .btns { + position: absolute; + right: 10px; + bottom: 0; + display: flex; + flex-direction: row; + gap: 10px; + z-index: 1; + } + .ivu-form .ivu-form-item-label, + .ivu-checkbox-wrapper { + font-size: 12px; + } + .ivu-input-wrapper { + .ivu-icon { + cursor: pointer; + } + } + } + .buttons { + padding: 0 9px; + line-height: 33px; + position: relative; + } .text-center { text-align: center; } } +.col-list { + .ivu-checkbox-group { + display: flex; + flex-direction: column; + } +} +.ivu-page { + padding: 9px; +} +.absolute { + position: absolute; + top: 0; + right: 180px; + padding: 0px; +} </style> \ No newline at end of file -- Gitblit v1.9.1