diff --git a/src/components/FormDialog/FormDialog.js b/src/components/FormDialog/FormDialog.js index 3d15ed0a..408b0dcf 100644 --- a/src/components/FormDialog/FormDialog.js +++ b/src/components/FormDialog/FormDialog.js @@ -1,5 +1,6 @@ import { cloneDeep, merge, isFunction, isBoolean } from 'lodash' import { renderVNode } from './vnode' +import styles from './formdialog.module.scss' export default { provide() { @@ -30,6 +31,8 @@ export default { dialogProps: { 'close-on-click-modal': false, 'append-to-body': true, + // 默认不全屏 + fullscreen: false, center: true }, op: { @@ -107,6 +110,9 @@ export default { this.$refs.form.clearValidate() } }, + toggleFullScreen() { + this.conf.dialogProps.fullscreen = !this.conf.dialogProps.fullscreen + }, _create(options) { // 合并配置 for (const name in this.conf) { @@ -133,7 +139,11 @@ export default { // 表单默认值 this.conf.items.forEach(e => { if (e.prop) { - this.$set(this.form, e.prop, this.form[e.prop] ? this.form[e.prop] : cloneDeep(e.value)) + this.$set( + this.form, + e.prop, + this.form[e.prop] ? this.form[e.prop] : cloneDeep(e.value) + ) } }) @@ -222,34 +232,49 @@ export default { return ( - + {/* 渲染表单列表 */} {items.map(e => { return ( - {e.component && !this._parseHidden({ value: e.hidden, scope: this.form }) && ( - + {e.component && + !this._parseHidden({ + value: e.hidden, + scope: this.form + }) && ( + {/* 将函数this绑定当前组件树实例。如果当前实例没有父实例,此实例将会是其自己。 */} - {renderVNode.call(this, e.component, { scope: this.form, $scopedSlots: this.$scopedSlots, prop: e.prop })} + {renderVNode.call(this, e.component, { + scope: this.form, + $scopedSlots: this.$scopedSlots, + prop: e.prop + })} )} @@ -259,17 +284,57 @@ export default { ) }, + /** + * 渲染标题区域 + */ + renderHeader() { + return ( +
+ {this.conf.title} + + +
+ ) + }, /** * 渲染底部按钮 */ renderFooter() { return ( - { this._beforeClose() } }} }> - { this.conf.op.cancelButtonText } + { + this._beforeClose() + } + } + }} + > + {this.conf.op.cancelButtonText} - { this._submit() } }} }> - { this.conf.op.saveButtonText } + { + this._submit() + } + } + }} + > + {this.conf.op.saveButtonText} ) @@ -279,31 +344,31 @@ export default { * render */ render() { - const { title, width, dialogProps } = this.conf + const { width, dialogProps } = this.conf return ( { + this.visible = v }, - on: { - 'update:visible': (v) => { this.visible = v }, - closed: this._onClosed - }, - directives: [{ name: 'el-drag-dialog' }] - } - } + closed: this._onClosed + }, + directives: [{ name: 'el-drag-dialog', arg: dialogProps.fullscreen ? 'fullscreen' : null }] + }} > + {this.renderForm()} {/* footer */} -
- {this.renderFooter()} -
+
) } diff --git a/src/components/FormDialog/formdialog.module.scss b/src/components/FormDialog/formdialog.module.scss new file mode 100644 index 00000000..443aa7cc --- /dev/null +++ b/src/components/FormDialog/formdialog.module.scss @@ -0,0 +1,29 @@ +.s-formdialog { + display: flex; + flex-direction: column; + + &__header { + position: relative; + display: flex; + justify-content: center; + align-items: center; + + &-icon { + display: inline-block; + cursor: pointer; + position: absolute; + top: 0; + right: 0; + color: #909399; + + &--fullscreen { + right: 16px; + margin-right: 10px; + } + } + } + + & :global(.el-dialog__body) { + flex: 1; + } +} diff --git a/src/core/directives/el-drag-dialog/drag.js b/src/core/directives/el-drag-dialog/drag.js index 299e9854..17820516 100644 --- a/src/core/directives/el-drag-dialog/drag.js +++ b/src/core/directives/el-drag-dialog/drag.js @@ -1,77 +1,101 @@ -export default { - bind(el, binding, vnode) { - const dialogHeaderEl = el.querySelector('.el-dialog__header') - const dragDom = el.querySelector('.el-dialog') - dialogHeaderEl.style.cssText += ';cursor:move;' - dragDom.style.cssText += ';top:0px;' +/** + * 配置拖拽 + */ +function setupDrag(el) { + const dialogHeaderEl = el.querySelector('.el-dialog__header') + const dragDom = el.querySelector('.el-dialog') + dialogHeaderEl.style.cssText += ';cursor:move;' + dragDom.style.cssText += ';top:0px;' - // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); - const getStyle = (function() { - if (window.document.currentStyle) { - return (dom, attr) => dom.currentStyle[attr] - } else { - return (dom, attr) => getComputedStyle(dom, false)[attr] - } - })() + // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); + const getStyle = (function() { + if (window.document.currentStyle) { + return (dom, attr) => dom.currentStyle[attr] + } else { + return (dom, attr) => getComputedStyle(dom, false)[attr] + } + })() - dialogHeaderEl.onmousedown = (e) => { - // 鼠标按下,计算当前元素距离可视区的距离 - const disX = e.clientX - dialogHeaderEl.offsetLeft - const disY = e.clientY - dialogHeaderEl.offsetTop + dialogHeaderEl.onmousedown = e => { + // 鼠标按下,计算当前元素距离可视区的距离 + const disX = e.clientX - dialogHeaderEl.offsetLeft + const disY = e.clientY - dialogHeaderEl.offsetTop - const dragDomWidth = dragDom.offsetWidth - const dragDomHeight = dragDom.offsetHeight + const dragDomWidth = dragDom.offsetWidth + const dragDomHeight = dragDom.offsetHeight - const screenWidth = document.body.clientWidth - const screenHeight = document.body.clientHeight + const screenWidth = document.body.clientWidth + const screenHeight = document.body.clientHeight - const minDragDomLeft = dragDom.offsetLeft - const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth + const minDragDomLeft = dragDom.offsetLeft + const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth - const minDragDomTop = dragDom.offsetTop - const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight + const minDragDomTop = dragDom.offsetTop + const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight - // 获取到的值带px 正则匹配替换 - let styL = getStyle(dragDom, 'left') - let styT = getStyle(dragDom, 'top') + // 获取到的值带px 正则匹配替换 + let styL = getStyle(dragDom, 'left') + let styT = getStyle(dragDom, 'top') - if (styL.includes('%')) { - styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100) - styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100) - } else { - styL = +styL.replace(/\px/g, '') - styT = +styT.replace(/\px/g, '') - } + if (styL.includes('%')) { + styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100) + styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100) + } else { + styL = +styL.replace(/\px/g, '') + styT = +styT.replace(/\px/g, '') + } - document.onmousemove = function(e) { - // 通过事件委托,计算移动的距离 - let left = e.clientX - disX - let top = e.clientY - disY + document.onmousemove = function(e) { + // 通过事件委托,计算移动的距离 + let left = e.clientX - disX + let top = e.clientY - disY - // 边界处理 - if (-(left) > minDragDomLeft) { - left = -minDragDomLeft - } else if (left > maxDragDomLeft) { - left = maxDragDomLeft - } + // 边界处理 + if (-left > minDragDomLeft) { + left = -minDragDomLeft + } else if (left > maxDragDomLeft) { + left = maxDragDomLeft + } - if (-(top) > minDragDomTop) { - top = -minDragDomTop - } else if (top > maxDragDomTop) { - top = maxDragDomTop - } + if (-top > minDragDomTop) { + top = -minDragDomTop + } else if (top > maxDragDomTop) { + top = maxDragDomTop + } - // 移动当前元素 - dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;` + // 移动当前元素 + dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;` - // emit onDrag event - vnode.child.$emit('dragDialog') - } + // emit onDrag event + // vnode.child.$emit('dragDialog') + } - document.onmouseup = function(e) { - document.onmousemove = null - document.onmouseup = null - } + document.onmouseup = function(e) { + document.onmousemove = null + document.onmouseup = null + } + } +} + +export default { + bind(el, binding, vnode) { + setupDrag(el) + }, + update(el, binding, vnode) { + if (binding.oldArg === binding.arg) { + return + } + // 全屏下取消拖拽 + if (binding.arg === 'fullscreen') { + const dialogHeaderEl = el.querySelector('.el-dialog__header') + const dragDom = el.querySelector('.el-dialog') + // 全屏模式下恢复 + dialogHeaderEl.style.cssText += ';cursor:auto;' + dragDom.style.cssText += ';top:0px;left:0px;' + dialogHeaderEl.onmousedown = null + } else { + // 恢复拖拽 + setupDrag(el) } } }