diff --git a/vue/src/asset/style/element-ui.scss b/vue/src/asset/style/element-ui.scss
index c58301a..727ba3c 100644
--- a/vue/src/asset/style/element-ui.scss
+++ b/vue/src/asset/style/element-ui.scss
@@ -236,3 +236,22 @@
background: transparent;
}
}
+
+.el-upload {
+ $size: 100px;
+
+ &-list__item-thumbnail {
+ object-fit: cover;
+ }
+
+ &.el-upload--picture-card {
+ height: $size;
+ width: $size;
+ line-height: $size;
+ }
+
+ &-list .el-upload-list__item {
+ height: $size;
+ width: $size;
+ }
+}
diff --git a/vue/src/asset/style/index.scss b/vue/src/asset/style/index.scss
index 9404486..795875b 100644
--- a/vue/src/asset/style/index.scss
+++ b/vue/src/asset/style/index.scss
@@ -84,32 +84,37 @@ a:hover {
/*----------路由页面的最大高度开始----------*/
$page-header-offsetHeight: $page-header-line-height + #{$page-view-margin * 2};
+.max-view-height.full {
+ height: 100vh;
+}
+
.max-view-height {
- height: calc(100vh - #{$page-view-margin * 2});
+ overflow-y: hidden;
+ max-height: calc(100vh - #{$page-view-margin * 2});
}
.has-nav .max-view-height {
- height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height});
+ max-height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height});
}
.has-tags-view .max-view-height {
- height: calc(100vh - #{$page-view-margin * 2} - #{$tags-view-height});
+ max-height: calc(100vh - #{$page-view-margin * 2} - #{$tags-view-height});
}
.has-page-header .max-view-height {
- height: calc(100vh - #{$page-view-margin * 2} - #{$page-header-offsetHeight});
+ max-height: calc(100vh - #{$page-view-margin * 2} - #{$page-header-offsetHeight});
}
.has-nav.has-tags-view .max-view-height {
- height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height} - #{$tags-view-height});
+ max-height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height} - #{$tags-view-height});
}
.has-nav .has-page-header .max-view-height {
- height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height} - #{$page-header-offsetHeight});
+ max-height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height} - #{$page-header-offsetHeight});
}
.has-nav.has-tags-view .has-page-header .max-view-height {
- height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height} - #{$tags-view-height} - #{$page-header-offsetHeight});
+ max-height: calc(100vh - #{$page-view-margin * 2} - #{$nav-height} - #{$tags-view-height} - #{$page-header-offsetHeight});
}
/*----------路由页面的最大高度结束----------*/
diff --git a/vue/src/asset/style/variables.scss b/vue/src/asset/style/variables.scss
index fc3cefc..5e3122d 100644
--- a/vue/src/asset/style/variables.scss
+++ b/vue/src/asset/style/variables.scss
@@ -91,5 +91,6 @@ $dialog-top: 100px;
success: $--color-success;
danger: $--color-danger;
warning: $--color-warning;
+ pageViewMargin: $page-view-margin;
dialogTop: $dialog-top;
}
diff --git a/vue/src/component/OrgTree/OrgTreeNode.vue b/vue/src/component/OrgTree/OrgTreeNode.vue
index 8e58376..abd4817 100644
--- a/vue/src/component/OrgTree/OrgTreeNode.vue
+++ b/vue/src/component/OrgTree/OrgTreeNode.vue
@@ -31,7 +31,6 @@ const renderNode = (h, data, context) => {
const renderLabel = (h, data, context) => {
const {props} = context
const label = data[props.props.label]
- const nodeRender = props.nodeRender
const clickHandler = context.listeners['on-node-click']
const mousedownHandler = e => {
e.stopPropagation()
@@ -44,10 +43,7 @@ const renderLabel = (h, data, context) => {
const touchleaveHandler = context.listeners['on-node-touchleave']
const childNodes = []
- if (typeof nodeRender === 'function') {
- childNodes.push(nodeRender(h, data))
- }
- else if (context.parent.$scopedSlots.default) {
+ if (context.parent.$scopedSlots.default) {
childNodes.push(context.parent.$scopedSlots.default(data))
}
else childNodes.push(label)
@@ -97,7 +93,7 @@ const renderBtn = (h, data, context) => {
return (
- {props.buttonRender ? props.buttonRender(h, data) : }
+
)
}
diff --git a/vue/src/component/OrgTree/index.vue b/vue/src/component/OrgTree/index.vue
index b9dc3d8..f02333f 100644
--- a/vue/src/component/OrgTree/index.vue
+++ b/vue/src/component/OrgTree/index.vue
@@ -8,8 +8,6 @@
:label-width="labelWidth"
:collapsable="collapsable"
:label-class-name="labelClassName"
- :node-render="nodeRender"
- :button-render="buttonRender"
@on-expand="handleExpand"
@on-node-click="handleNodeClick"
/>
@@ -38,8 +36,6 @@ export default {
},
horizontal: Boolean,
collapsable: Boolean,
- nodeRender: Function,
- buttonRender: Function,
labelWidth: [String, Number],
labelClassName: [Function, String],
expandAll: Boolean
diff --git a/vue/src/component/UploadFile/style.scss b/vue/src/component/UploadFile/style.scss
index d14fc61..613fa6a 100644
--- a/vue/src/component/UploadFile/style.scss
+++ b/vue/src/component/UploadFile/style.scss
@@ -29,10 +29,6 @@
}
}
-.el-upload-list__item-thumbnail {
- object-fit: cover;
-}
-
.upload-tooltip {
max-width: 146px;
}
diff --git a/vue/src/component/abstract/Dialog/style.scss b/vue/src/component/abstract/Dialog/style.scss
index f254a21..6789556 100644
--- a/vue/src/component/abstract/Dialog/style.scss
+++ b/vue/src/component/abstract/Dialog/style.scss
@@ -14,16 +14,5 @@
.el-form {
padding: 0;
}
-
- .el-upload.el-upload--picture-card {
- height: 100px;
- width: 100px;
- line-height: 105px;
- }
-
- .el-upload-list .el-upload-list__item {
- height: 100px;
- width: 100px;
- }
}
}
diff --git a/vue/src/component/form/Search/index.vue b/vue/src/component/form/Search/index.vue
index 87f5bc1..67acd5c 100644
--- a/vue/src/component/form/Search/index.vue
+++ b/vue/src/component/form/Search/index.vue
@@ -102,7 +102,7 @@ export default {
this.initialModel = deepClone(this.model)
this.resize()
- this.resizeObserver = new ResizeObserver(() => this.resize())
+ this.resizeObserver = new ResizeObserver(this.resize)
this.resizeObserver.observe(this.$el.parentNode)
this.$once('hook:beforeDestroy', () => {
diff --git a/vue/src/layout/component/Header/component/Navbar/component/HeadMenu.vue b/vue/src/layout/component/Header/component/Navbar/component/HeadMenu.vue
index 3b2312e..bc05745 100644
--- a/vue/src/layout/component/Header/component/Navbar/component/HeadMenu.vue
+++ b/vue/src/layout/component/Header/component/Navbar/component/HeadMenu.vue
@@ -138,8 +138,12 @@ export default {
//如果已创建observer,则返回
if (this.resizeObserver) return
- this.resizeObserver = new ResizeObserver(() => this.resize())
+ this.resizeObserver = new ResizeObserver(this.resize)
this.resizeObserver.observe(this.getMenuEl())
+
+ this.$once('hook:beforeDestroy', () => {
+ this.resizeObserver && this.resizeObserver.disconnect()
+ })
},
renderVisibleMenus(h, visibleMenus) {
@@ -162,10 +166,6 @@ export default {
mounted() {
this.setChildrenWidth()
this.createResizeObserver()
-
- this.$once('hook:beforeDestroy', () => {
- this.resizeObserver && this.resizeObserver.disconnect()
- })
},
render(h) {
diff --git a/vue/src/mixin/chart/resize.js b/vue/src/mixin/chart/resize.js
index 59cde3e..33d8081 100644
--- a/vue/src/mixin/chart/resize.js
+++ b/vue/src/mixin/chart/resize.js
@@ -3,7 +3,7 @@ import {debounce} from '@/util'
export default {
methods: {
$_initResizeEvent() {
- this.resizeObserver = new ResizeObserver(() => this.$_resizeHandler())
+ this.resizeObserver = new ResizeObserver(this.$_resizeHandler)
this.resizeObserver.observe(this.$el)
},
$_destroyResizeEvent() {
diff --git a/vue/src/view/app/common/ListPage/autoAdaptHeightMixin.js b/vue/src/view/app/common/ListPage/autoAdaptHeightMixin.js
new file mode 100644
index 0000000..3b8dff6
--- /dev/null
+++ b/vue/src/view/app/common/ListPage/autoAdaptHeightMixin.js
@@ -0,0 +1,56 @@
+/**
+ * 列表页自适应混入
+ * 监听el-table,动态设置max-height属性
+ */
+
+import cssVariables from "@/asset/style/variables.scss"
+import {debounce} from "@/util"
+
+export default {
+ data() {
+ return {
+ tableMaxHeight: undefined
+ }
+ },
+
+ methods: {
+ resize() {
+ const clientHeight = window.innerHeight
+ const pageViewMargin = parseFloat(cssVariables['pageViewMargin'])
+
+ //计算表格底部距离视窗底部的距离
+ const tableRect = this.$refs.table.$el.getBoundingClientRect()
+ const bottomDistanceBetweenWindowAndTable = clientHeight - tableRect.top - tableRect.height
+
+ //判断有无分页组件,分页组件总高度为70px(本身50px高度,margin-top 20px)
+ const paginationHeight = this.$el.querySelector('.table-container > .el-pagination') ? 70 : 0
+
+ //表格距离视窗底部的理想距离(分页高度 + el-card的1px边距 + el-card padding + 页面margin)
+ const bottomDistanceBetweenWindowAndTableShouldBe =
+ paginationHeight
+ + 1
+ + 20
+ + pageViewMargin
+
+ const overHeight = bottomDistanceBetweenWindowAndTableShouldBe - bottomDistanceBetweenWindowAndTable
+ if (overHeight > 0) {
+ this.tableMaxHeight = tableRect.height - overHeight
+ }
+ },
+ createResizeObserver() {
+ if (this.resizeObserver) return
+
+ this.resizeObserver = new ResizeObserver(this.resize)
+ this.resizeObserver.observe(this.$refs.table.$el)
+
+ this.$once('hook:beforeDestroy', () => {
+ this.resizeObserver && this.resizeObserver.disconnect()
+ })
+ },
+ },
+
+ mounted() {
+ this.resize = debounce(this.resize, 300)
+ this.createResizeObserver()
+ }
+}
diff --git a/vue/src/view/app/common/ListPage/index.vue b/vue/src/view/app/common/ListPage/index.vue
index 9225339..5cd3b63 100644
--- a/vue/src/view/app/common/ListPage/index.vue
+++ b/vue/src/view/app/common/ListPage/index.vue
@@ -2,69 +2,75 @@
import AbstractTable from "@/component/abstract/Table"
import AbstractPagination from "@/component/abstract/Pagination"
import SearchForm from "@/component/form/Search"
+import autoAdaptHeightMixin from "./autoAdaptHeightMixin"
import {isEmpty} from "@/util"
-const renderSearchForm = (h, config, slot) => {
- return slot && {slot()}
-}
+export default {
+ name: "ListPage",
-const renderButtons = (h, buttons) => {
- if (buttons.length > 0 && isEmpty(buttons[0].type)) {
- buttons[0].type = 'primary'
- }
- return (
-
- {buttons.map(button => {
- if (!button) return
- const {icon, type, content, e} = button
- return (
-
- {content}
-
- )
- })}
-
- )
-}
+ mixins: [autoAdaptHeightMixin],
-const renderList = (h, {loading, tableConfig, tableColumn, paginationConfig}) => {
- return (
-
- {tableColumn()}
-
-
- )
-}
+ components: {AbstractTable, AbstractPagination, SearchForm},
-export default {
- name: "ListPage",
+ props: {data: Object},
- functional: true,
+ methods: {
+ renderSearchForm(config, slot) {
+ return slot && {slot()}
+ },
+ renderButtons(buttons) {
+ if (buttons.length > 0 && isEmpty(buttons[0].type)) {
+ buttons[0].type = 'primary'
+ }
+ return (
+
+ {buttons.map(button => {
+ if (!button) return
+ const {icon, type, content, e} = button
+ return (
+
+ {content}
+
+ )
+ })}
+
+ )
+ },
+ renderTableAndPagination({loading, table, pagination}) {
+ //为了配合autoAdaptHeightMixin
+ if (!table.props || !table.props.maxHeight) {
+ table.props.maxHeight = this.tableMaxHeight
+ }
- props: {
- data: Object
+ return (
+
+
+
+
+ )
+ }
},
- render(h, context) {
- const {props: {data: {pageLoading, buttons, dataLoading, search, table, pagination}}, scopedSlots} = context
+ render() {
+ const {data: {pageLoading, buttons, dataLoading, search, table, pagination}, $scopedSlots} = this
+
+ if (!table.scopedSlots) {
+ table.scopedSlots = {}
+ }
+ table.scopedSlots.default = $scopedSlots.tableColumn
return (
-
- {renderSearchForm(h, search, scopedSlots.searchForm)}
- {renderButtons(h, buttons)}
- {renderList(h, {
- loading: dataLoading,
- tableConfig: table,
- tableColumn: scopedSlots.tableColumn,
- paginationConfig: pagination
- })}
- {scopedSlots.default && scopedSlots.default()}
+
+ {this.renderSearchForm(search, $scopedSlots.searchForm)}
+ {this.renderButtons(buttons)}
+ {this.renderTableAndPagination({loading: dataLoading, table, pagination})}
+ {$scopedSlots.default && $scopedSlots.default()}
)
}
diff --git a/vue/src/view/system/category/component/List.vue b/vue/src/view/system/category/component/List.vue
index b84b51a..d41de55 100644
--- a/vue/src/view/system/category/component/List.vue
+++ b/vue/src/view/system/category/component/List.vue
@@ -1,5 +1,5 @@
-
+
diff --git a/vue/src/view/system/department/indexPage.vue b/vue/src/view/system/department/indexPage.vue
index f4d1278..b3ac6f8 100644
--- a/vue/src/view/system/department/indexPage.vue
+++ b/vue/src/view/system/department/indexPage.vue
@@ -1,5 +1,5 @@
-
+