From a29201a248374689bf683bbe0ce489d579483e85 Mon Sep 17 00:00:00 2001 From: 稚屿 <1491182878@qq.com> Date: 星期三, 09 二月 2022 08:46:54 +0800 Subject: [PATCH] 修正单词拼写错误 --- ruoyi-ui/src/views/tool/build/index.vue | 1566 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 783 insertions(+), 783 deletions(-) diff --git a/ruoyi-ui/src/views/tool/build/index.vue b/ruoyi-ui/src/views/tool/build/index.vue index e511408..d679422 100644 --- a/ruoyi-ui/src/views/tool/build/index.vue +++ b/ruoyi-ui/src/views/tool/build/index.vue @@ -1,783 +1,783 @@ -<template> - <div class="container"> - <div class="left-board"> - <div class="logo-wrapper"> - <div class="logo"> - <img :src="logo" alt="logo"> Form Generator - </div> - </div> - <el-scrollbar class="left-scrollbar"> - <div class="components-list"> - <div class="components-title"> - <svg-icon icon-class="component" />输入型组件 - </div> - <draggable - class="components-draggable" - :list="inputComponents" - :group="{ name: 'componentsGroup', pull: 'clone', put: false }" - :clone="cloneComponent" - draggable=".components-item" - :sort="false" - @end="onEnd" - > - <div - v-for="(element, index) in inputComponents" :key="index" class="components-item" - @click="addComponent(element)" - > - <div class="components-body"> - <svg-icon :icon-class="element.tagIcon" /> - {{ element.label }} - </div> - </div> - </draggable> - <div class="components-title"> - <svg-icon icon-class="component" />选择型组件 - </div> - <draggable - class="components-draggable" - :list="selectComponents" - :group="{ name: 'componentsGroup', pull: 'clone', put: false }" - :clone="cloneComponent" - draggable=".components-item" - :sort="false" - @end="onEnd" - > - <div - v-for="(element, index) in selectComponents" - :key="index" - class="components-item" - @click="addComponent(element)" - > - <div class="components-body"> - <svg-icon :icon-class="element.tagIcon" /> - {{ element.label }} - </div> - </div> - </draggable> - <div class="components-title"> - <svg-icon icon-class="component" /> 布局型组件 - </div> - <draggable - class="components-draggable" :list="layoutComponents" - :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent" - draggable=".components-item" :sort="false" @end="onEnd" - > - <div - v-for="(element, index) in layoutComponents" :key="index" class="components-item" - @click="addComponent(element)" - > - <div class="components-body"> - <svg-icon :icon-class="element.tagIcon" /> - {{ element.label }} - </div> - </div> - </draggable> - </div> - </el-scrollbar> - </div> - - <div class="center-board"> - <div class="action-bar"> - <el-button icon="el-icon-download" type="text" @click="download"> - 导出vue文件 - </el-button> - <el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy"> - 复制代码 - </el-button> - <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty"> - 清空 - </el-button> - </div> - <el-scrollbar class="center-scrollbar"> - <el-row class="center-board-row" :gutter="formConf.gutter"> - <el-form - :size="formConf.size" - :label-position="formConf.labelPosition" - :disabled="formConf.disabled" - :label-width="formConf.labelWidth + 'px'" - > - <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"> - <draggable-item - v-for="(element, index) in drawingList" - :key="element.renderKey" - :drawing-list="drawingList" - :element="element" - :index="index" - :active-id="activeId" - :form-conf="formConf" - @activeItem="activeFormItem" - @copyItem="drawingItemCopy" - @deleteItem="drawingItemDelete" - /> - </draggable> - <div v-show="!drawingList.length" class="empty-info"> - 从左侧拖入或点选组件进行表单设计 - </div> - </el-form> - </el-row> - </el-scrollbar> - </div> - - <right-panel - :active-data="activeData" - :form-conf="formConf" - :show-field="!!drawingList.length" - @tag-change="tagChange" - /> - - <code-type-dialog - :visible.sync="dialogVisible" - title="选择生成类型" - :show-file-name="showFileName" - @confirm="generate" - /> - <input id="copyNode" type="hidden"> - </div> -</template> - -<script> -import draggable from 'vuedraggable' -import beautifier from 'js-beautify' -import ClipboardJS from 'clipboard' -import render from '@/utils/generator/render' -import RightPanel from './RightPanel' -import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config' -import { beautifierConf, titleCase } from '@/utils/index' -import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' -import { makeUpJs } from '@/utils/generator/js' -import { makeUpCss } from '@/utils/generator/css' -import drawingDefalut from '@/utils/generator/drawingDefalut' -import logo from '@/assets/logo/logo.png' -import CodeTypeDialog from './CodeTypeDialog' -import DraggableItem from './DraggableItem' - -let oldActiveId -let tempActiveData - -export default { - components: { - draggable, - render, - RightPanel, - CodeTypeDialog, - DraggableItem - }, - data() { - return { - logo, - idGlobal: 100, - formConf, - inputComponents, - selectComponents, - layoutComponents, - labelWidth: 100, - drawingList: drawingDefalut, - drawingData: {}, - activeId: drawingDefalut[0].formId, - drawerVisible: false, - formData: {}, - dialogVisible: false, - generateConf: null, - showFileName: false, - activeData: drawingDefalut[0] - } - }, - created() { - // 防止 firefox 下 拖拽 会新打卡一个选项卡 - document.body.ondrop = event => { - event.preventDefault() - event.stopPropagation() - } - }, - watch: { - // eslint-disable-next-line func-names - 'activeData.label': function (val, oldVal) { - if ( - this.activeData.placeholder === undefined - || !this.activeData.tag - || oldActiveId !== this.activeId - ) { - return - } - this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val - }, - activeId: { - handler(val) { - oldActiveId = val - }, - immediate: true - } - }, - mounted() { - const clipboard = new ClipboardJS('#copyNode', { - text: trigger => { - const codeStr = this.generateCode() - this.$notify({ - title: '成功', - message: '代码已复制到剪切板,可粘贴。', - type: 'success' - }) - return codeStr - } - }) - clipboard.on('error', e => { - this.$message.error('代码复制失败') - }) - }, - methods: { - activeFormItem(element) { - this.activeData = element - this.activeId = element.formId - }, - onEnd(obj, a) { - if (obj.from !== obj.to) { - this.activeData = tempActiveData - this.activeId = this.idGlobal - } - }, - addComponent(item) { - const clone = this.cloneComponent(item) - this.drawingList.push(clone) - this.activeFormItem(clone) - }, - cloneComponent(origin) { - const clone = JSON.parse(JSON.stringify(origin)) - clone.formId = ++this.idGlobal - clone.span = formConf.span - clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件 - if (!clone.layout) clone.layout = 'colFormItem' - if (clone.layout === 'colFormItem') { - clone.vModel = `field${this.idGlobal}` - clone.placeholder !== undefined && (clone.placeholder += clone.label) - tempActiveData = clone - } else if (clone.layout === 'rowFormItem') { - delete clone.label - clone.componentName = `row${this.idGlobal}` - clone.gutter = this.formConf.gutter - tempActiveData = clone - } - return tempActiveData - }, - AssembleFormData() { - this.formData = { - fields: JSON.parse(JSON.stringify(this.drawingList)), - ...this.formConf - } - }, - generate(data) { - const func = this[`exec${titleCase(this.operationType)}`] - this.generateConf = data - func && func(data) - }, - execRun(data) { - this.AssembleFormData() - this.drawerVisible = true - }, - execDownload(data) { - const codeStr = this.generateCode() - const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }) - this.$download.saveAs(blob, data.fileName) - }, - execCopy(data) { - document.getElementById('copyNode').click() - }, - empty() { - this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then( - () => { - this.drawingList = [] - } - ) - }, - drawingItemCopy(item, parent) { - let clone = JSON.parse(JSON.stringify(item)) - clone = this.createIdAndKey(clone) - parent.push(clone) - this.activeFormItem(clone) - }, - createIdAndKey(item) { - item.formId = ++this.idGlobal - item.renderKey = +new Date() - if (item.layout === 'colFormItem') { - item.vModel = `field${this.idGlobal}` - } else if (item.layout === 'rowFormItem') { - item.componentName = `row${this.idGlobal}` - } - if (Array.isArray(item.children)) { - item.children = item.children.map(childItem => this.createIdAndKey(childItem)) - } - return item - }, - drawingItemDelete(index, parent) { - parent.splice(index, 1) - this.$nextTick(() => { - const len = this.drawingList.length - if (len) { - this.activeFormItem(this.drawingList[len - 1]) - } - }) - }, - generateCode() { - const { type } = this.generateConf - this.AssembleFormData() - const script = vueScript(makeUpJs(this.formData, type)) - const html = vueTemplate(makeUpHtml(this.formData, type)) - const css = cssStyle(makeUpCss(this.formData)) - return beautifier.html(html + script + css, beautifierConf.html) - }, - download() { - this.dialogVisible = true - this.showFileName = true - this.operationType = 'download' - }, - run() { - this.dialogVisible = true - this.showFileName = false - this.operationType = 'run' - }, - copy() { - this.dialogVisible = true - this.showFileName = false - this.operationType = 'copy' - }, - tagChange(newTag) { - newTag = this.cloneComponent(newTag) - newTag.vModel = this.activeData.vModel - newTag.formId = this.activeId - newTag.span = this.activeData.span - delete this.activeData.tag - delete this.activeData.tagIcon - delete this.activeData.document - Object.keys(newTag).forEach(key => { - if (this.activeData[key] !== undefined - && typeof this.activeData[key] === typeof newTag[key]) { - newTag[key] = this.activeData[key] - } - }) - this.activeData = newTag - this.updateDrawingList(newTag, this.drawingList) - }, - updateDrawingList(newTag, list) { - const index = list.findIndex(item => item.formId === this.activeId) - if (index > -1) { - list.splice(index, 1, newTag) - } else { - list.forEach(item => { - if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children) - }) - } - } - } -} -</script> - -<style lang='scss'> -body, html{ - margin: 0; - padding: 0; - background: #fff; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; -} - -input, textarea{ - font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; -} - -.editor-tabs{ - background: #121315; - .el-tabs__header{ - margin: 0; - border-bottom-color: #121315; - .el-tabs__nav{ - border-color: #121315; - } - } - .el-tabs__item{ - height: 32px; - line-height: 32px; - color: #888a8e; - border-left: 1px solid #121315 !important; - background: #363636; - margin-right: 5px; - user-select: none; - } - .el-tabs__item.is-active{ - background: #1e1e1e; - border-bottom-color: #1e1e1e!important; - color: #fff; - } - .el-icon-edit{ - color: #f1fa8c; - } - .el-icon-document{ - color: #a95812; - } -} - -// home -.right-scrollbar { - .el-scrollbar__view { - padding: 12px 18px 15px 15px; - } -} -.left-scrollbar .el-scrollbar__wrap { - box-sizing: border-box; - overflow-x: hidden !important; - margin-bottom: 0 !important; -} -.center-tabs{ - .el-tabs__header{ - margin-bottom: 0!important; - } - .el-tabs__item{ - width: 50%; - text-align: center; - } - .el-tabs__nav{ - width: 100%; - } -} -.reg-item{ - padding: 12px 6px; - background: #f8f8f8; - position: relative; - border-radius: 4px; - .close-btn{ - position: absolute; - right: -6px; - top: -6px; - display: block; - width: 16px; - height: 16px; - line-height: 16px; - background: rgba(0, 0, 0, 0.2); - border-radius: 50%; - color: #fff; - text-align: center; - z-index: 1; - cursor: pointer; - font-size: 12px; - &:hover{ - background: rgba(210, 23, 23, 0.5) - } - } - & + .reg-item{ - margin-top: 18px; - } -} -.action-bar{ - & .el-button+.el-button { - margin-left: 15px; - } - & i { - font-size: 20px; - vertical-align: middle; - position: relative; - top: -1px; - } -} - -.custom-tree-node{ - width: 100%; - font-size: 14px; - .node-operation{ - float: right; - } - i[class*="el-icon"] + i[class*="el-icon"]{ - margin-left: 6px; - } - .el-icon-plus{ - color: #409EFF; - } - .el-icon-delete{ - color: #157a0c; - } -} - -.left-scrollbar .el-scrollbar__view{ - overflow-x: hidden; -} - -.el-rate{ - display: inline-block; - vertical-align: text-top; -} -.el-upload__tip{ - line-height: 1.2; -} - -$selectedColor: #f6f7ff; -$lighterBlue: #409EFF; - -.container { - position: relative; - width: 100%; - height: 100%; -} - -.components-list { - padding: 8px; - box-sizing: border-box; - height: 100%; - .components-item { - display: inline-block; - width: 48%; - margin: 1%; - transition: transform 0ms !important; - } -} -.components-draggable{ - padding-bottom: 20px; -} -.components-title{ - font-size: 14px; - color: #222; - margin: 6px 2px; - .svg-icon{ - color: #666; - font-size: 18px; - } -} - -.components-body { - padding: 8px 10px; - background: $selectedColor; - font-size: 12px; - cursor: move; - border: 1px dashed $selectedColor; - border-radius: 3px; - .svg-icon{ - color: #777; - font-size: 15px; - } - &:hover { - border: 1px dashed #787be8; - color: #787be8; - .svg-icon { - color: #787be8; - } - } -} - -.left-board { - width: 260px; - position: absolute; - left: 0; - top: 0; - height: 100vh; -} -.left-scrollbar{ - height: calc(100vh - 42px); - overflow: hidden; -} -.center-scrollbar { - height: calc(100vh - 42px); - overflow: hidden; - border-left: 1px solid #f1e8e8; - border-right: 1px solid #f1e8e8; - box-sizing: border-box; -} -.center-board { - height: 100vh; - width: auto; - margin: 0 350px 0 260px; - box-sizing: border-box; -} -.empty-info{ - position: absolute; - top: 46%; - left: 0; - right: 0; - text-align: center; - font-size: 18px; - color: #ccb1ea; - letter-spacing: 4px; -} -.action-bar{ - position: relative; - height: 42px; - text-align: right; - padding: 0 15px; - box-sizing: border-box;; - border: 1px solid #f1e8e8; - border-top: none; - border-left: none; - .delete-btn{ - color: #F56C6C; - } -} -.logo-wrapper{ - position: relative; - height: 42px; - background: #fff; - border-bottom: 1px solid #f1e8e8; - box-sizing: border-box; -} -.logo{ - position: absolute; - left: 12px; - top: 6px; - line-height: 30px; - color: #00afff; - font-weight: 600; - font-size: 17px; - white-space: nowrap; - > img{ - width: 30px; - height: 30px; - vertical-align: top; - } - .github{ - display: inline-block; - vertical-align: sub; - margin-left: 15px; - > img{ - height: 22px; - } - } -} - -.center-board-row { - padding: 12px 12px 15px 12px; - box-sizing: border-box; - & > .el-form { - // 69 = 12+15+42 - height: calc(100vh - 69px); - } -} -.drawing-board { - height: 100%; - position: relative; - .components-body { - padding: 0; - margin: 0; - font-size: 0; - } - .sortable-ghost { - position: relative; - display: block; - overflow: hidden; - &::before { - content: " "; - position: absolute; - left: 0; - right: 0; - top: 0; - height: 3px; - background: rgb(89, 89, 223); - z-index: 2; - } - } - .components-item.sortable-ghost { - width: 100%; - height: 60px; - background-color: $selectedColor; - } - .active-from-item { - & > .el-form-item{ - background: $selectedColor; - border-radius: 6px; - } - & > .drawing-item-copy, & > .drawing-item-delete{ - display: initial; - } - & > .component-name{ - color: $lighterBlue; - } - } - .el-form-item{ - margin-bottom: 15px; - } -} -.drawing-item{ - position: relative; - cursor: move; - &.unfocus-bordered:not(.activeFromItem) > div:first-child { - border: 1px dashed #ccc; - } - .el-form-item{ - padding: 12px 10px; - } -} -.drawing-row-item{ - position: relative; - cursor: move; - box-sizing: border-box; - border: 1px dashed #ccc; - border-radius: 3px; - padding: 0 2px; - margin-bottom: 15px; - .drawing-row-item { - margin-bottom: 2px; - } - .el-col{ - margin-top: 22px; - } - .el-form-item{ - margin-bottom: 0; - } - .drag-wrapper{ - min-height: 80px; - } - &.active-from-item{ - border: 1px dashed $lighterBlue; - } - .component-name{ - position: absolute; - top: 0; - left: 0; - font-size: 12px; - color: #bbb; - display: inline-block; - padding: 0 6px; - } -} -.drawing-item, .drawing-row-item{ - &:hover { - & > .el-form-item{ - background: $selectedColor; - border-radius: 6px; - } - & > .drawing-item-copy, & > .drawing-item-delete{ - display: initial; - } - } - & > .drawing-item-copy, & > .drawing-item-delete{ - display: none; - position: absolute; - top: -10px; - width: 22px; - height: 22px; - line-height: 22px; - text-align: center; - border-radius: 50%; - font-size: 12px; - border: 1px solid; - cursor: pointer; - z-index: 1; - } - & > .drawing-item-copy{ - right: 56px; - border-color: $lighterBlue; - color: $lighterBlue; - background: #fff; - &:hover{ - background: $lighterBlue; - color: #fff; - } - } - & > .drawing-item-delete{ - right: 24px; - border-color: #F56C6C; - color: #F56C6C; - background: #fff; - &:hover{ - background: #F56C6C; - color: #fff; - } - } -} - -</style> +<template> + <div class="container"> + <div class="left-board"> + <div class="logo-wrapper"> + <div class="logo"> + <img :src="logo" alt="logo"> Form Generator + </div> + </div> + <el-scrollbar class="left-scrollbar"> + <div class="components-list"> + <div class="components-title"> + <svg-icon icon-class="component" />输入型组件 + </div> + <draggable + class="components-draggable" + :list="inputComponents" + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" + :clone="cloneComponent" + draggable=".components-item" + :sort="false" + @end="onEnd" + > + <div + v-for="(element, index) in inputComponents" :key="index" class="components-item" + @click="addComponent(element)" + > + <div class="components-body"> + <svg-icon :icon-class="element.tagIcon" /> + {{ element.label }} + </div> + </div> + </draggable> + <div class="components-title"> + <svg-icon icon-class="component" />选择型组件 + </div> + <draggable + class="components-draggable" + :list="selectComponents" + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" + :clone="cloneComponent" + draggable=".components-item" + :sort="false" + @end="onEnd" + > + <div + v-for="(element, index) in selectComponents" + :key="index" + class="components-item" + @click="addComponent(element)" + > + <div class="components-body"> + <svg-icon :icon-class="element.tagIcon" /> + {{ element.label }} + </div> + </div> + </draggable> + <div class="components-title"> + <svg-icon icon-class="component" /> 布局型组件 + </div> + <draggable + class="components-draggable" :list="layoutComponents" + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent" + draggable=".components-item" :sort="false" @end="onEnd" + > + <div + v-for="(element, index) in layoutComponents" :key="index" class="components-item" + @click="addComponent(element)" + > + <div class="components-body"> + <svg-icon :icon-class="element.tagIcon" /> + {{ element.label }} + </div> + </div> + </draggable> + </div> + </el-scrollbar> + </div> + + <div class="center-board"> + <div class="action-bar"> + <el-button icon="el-icon-download" type="text" @click="download"> + 导出vue文件 + </el-button> + <el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy"> + 复制代码 + </el-button> + <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty"> + 清空 + </el-button> + </div> + <el-scrollbar class="center-scrollbar"> + <el-row class="center-board-row" :gutter="formConf.gutter"> + <el-form + :size="formConf.size" + :label-position="formConf.labelPosition" + :disabled="formConf.disabled" + :label-width="formConf.labelWidth + 'px'" + > + <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"> + <draggable-item + v-for="(element, index) in drawingList" + :key="element.renderKey" + :drawing-list="drawingList" + :element="element" + :index="index" + :active-id="activeId" + :form-conf="formConf" + @activeItem="activeFormItem" + @copyItem="drawingItemCopy" + @deleteItem="drawingItemDelete" + /> + </draggable> + <div v-show="!drawingList.length" class="empty-info"> + 从左侧拖入或点选组件进行表单设计 + </div> + </el-form> + </el-row> + </el-scrollbar> + </div> + + <right-panel + :active-data="activeData" + :form-conf="formConf" + :show-field="!!drawingList.length" + @tag-change="tagChange" + /> + + <code-type-dialog + :visible.sync="dialogVisible" + title="选择生成类型" + :show-file-name="showFileName" + @confirm="generate" + /> + <input id="copyNode" type="hidden"> + </div> +</template> + +<script> +import draggable from 'vuedraggable' +import beautifier from 'js-beautify' +import ClipboardJS from 'clipboard' +import render from '@/utils/generator/render' +import RightPanel from './RightPanel' +import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config' +import { beautifierConf, titleCase } from '@/utils/index' +import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' +import { makeUpJs } from '@/utils/generator/js' +import { makeUpCss } from '@/utils/generator/css' +import drawingDefault from '@/utils/generator/drawingDefault' +import logo from '@/assets/logo/logo.png' +import CodeTypeDialog from './CodeTypeDialog' +import DraggableItem from './DraggableItem' + +let oldActiveId +let tempActiveData + +export default { + components: { + draggable, + render, + RightPanel, + CodeTypeDialog, + DraggableItem + }, + data() { + return { + logo, + idGlobal: 100, + formConf, + inputComponents, + selectComponents, + layoutComponents, + labelWidth: 100, + drawingList: drawingDefault, + drawingData: {}, + activeId: drawingDefault[0].formId, + drawerVisible: false, + formData: {}, + dialogVisible: false, + generateConf: null, + showFileName: false, + activeData: drawingDefault[0] + } + }, + created() { + // 防止 firefox 下 拖拽 会新打卡一个选项卡 + document.body.ondrop = event => { + event.preventDefault() + event.stopPropagation() + } + }, + watch: { + // eslint-disable-next-line func-names + 'activeData.label': function (val, oldVal) { + if ( + this.activeData.placeholder === undefined + || !this.activeData.tag + || oldActiveId !== this.activeId + ) { + return + } + this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val + }, + activeId: { + handler(val) { + oldActiveId = val + }, + immediate: true + } + }, + mounted() { + const clipboard = new ClipboardJS('#copyNode', { + text: trigger => { + const codeStr = this.generateCode() + this.$notify({ + title: '成功', + message: '代码已复制到剪切板,可粘贴。', + type: 'success' + }) + return codeStr + } + }) + clipboard.on('error', e => { + this.$message.error('代码复制失败') + }) + }, + methods: { + activeFormItem(element) { + this.activeData = element + this.activeId = element.formId + }, + onEnd(obj, a) { + if (obj.from !== obj.to) { + this.activeData = tempActiveData + this.activeId = this.idGlobal + } + }, + addComponent(item) { + const clone = this.cloneComponent(item) + this.drawingList.push(clone) + this.activeFormItem(clone) + }, + cloneComponent(origin) { + const clone = JSON.parse(JSON.stringify(origin)) + clone.formId = ++this.idGlobal + clone.span = formConf.span + clone.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件 + if (!clone.layout) clone.layout = 'colFormItem' + if (clone.layout === 'colFormItem') { + clone.vModel = `field${this.idGlobal}` + clone.placeholder !== undefined && (clone.placeholder += clone.label) + tempActiveData = clone + } else if (clone.layout === 'rowFormItem') { + delete clone.label + clone.componentName = `row${this.idGlobal}` + clone.gutter = this.formConf.gutter + tempActiveData = clone + } + return tempActiveData + }, + AssembleFormData() { + this.formData = { + fields: JSON.parse(JSON.stringify(this.drawingList)), + ...this.formConf + } + }, + generate(data) { + const func = this[`exec${titleCase(this.operationType)}`] + this.generateConf = data + func && func(data) + }, + execRun(data) { + this.AssembleFormData() + this.drawerVisible = true + }, + execDownload(data) { + const codeStr = this.generateCode() + const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }) + this.$download.saveAs(blob, data.fileName) + }, + execCopy(data) { + document.getElementById('copyNode').click() + }, + empty() { + this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then( + () => { + this.drawingList = [] + } + ) + }, + drawingItemCopy(item, parent) { + let clone = JSON.parse(JSON.stringify(item)) + clone = this.createIdAndKey(clone) + parent.push(clone) + this.activeFormItem(clone) + }, + createIdAndKey(item) { + item.formId = ++this.idGlobal + item.renderKey = +new Date() + if (item.layout === 'colFormItem') { + item.vModel = `field${this.idGlobal}` + } else if (item.layout === 'rowFormItem') { + item.componentName = `row${this.idGlobal}` + } + if (Array.isArray(item.children)) { + item.children = item.children.map(childItem => this.createIdAndKey(childItem)) + } + return item + }, + drawingItemDelete(index, parent) { + parent.splice(index, 1) + this.$nextTick(() => { + const len = this.drawingList.length + if (len) { + this.activeFormItem(this.drawingList[len - 1]) + } + }) + }, + generateCode() { + const { type } = this.generateConf + this.AssembleFormData() + const script = vueScript(makeUpJs(this.formData, type)) + const html = vueTemplate(makeUpHtml(this.formData, type)) + const css = cssStyle(makeUpCss(this.formData)) + return beautifier.html(html + script + css, beautifierConf.html) + }, + download() { + this.dialogVisible = true + this.showFileName = true + this.operationType = 'download' + }, + run() { + this.dialogVisible = true + this.showFileName = false + this.operationType = 'run' + }, + copy() { + this.dialogVisible = true + this.showFileName = false + this.operationType = 'copy' + }, + tagChange(newTag) { + newTag = this.cloneComponent(newTag) + newTag.vModel = this.activeData.vModel + newTag.formId = this.activeId + newTag.span = this.activeData.span + delete this.activeData.tag + delete this.activeData.tagIcon + delete this.activeData.document + Object.keys(newTag).forEach(key => { + if (this.activeData[key] !== undefined + && typeof this.activeData[key] === typeof newTag[key]) { + newTag[key] = this.activeData[key] + } + }) + this.activeData = newTag + this.updateDrawingList(newTag, this.drawingList) + }, + updateDrawingList(newTag, list) { + const index = list.findIndex(item => item.formId === this.activeId) + if (index > -1) { + list.splice(index, 1, newTag) + } else { + list.forEach(item => { + if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children) + }) + } + } + } +} +</script> + +<style lang='scss'> +body, html{ + margin: 0; + padding: 0; + background: #fff; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; +} + +input, textarea{ + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; +} + +.editor-tabs{ + background: #121315; + .el-tabs__header{ + margin: 0; + border-bottom-color: #121315; + .el-tabs__nav{ + border-color: #121315; + } + } + .el-tabs__item{ + height: 32px; + line-height: 32px; + color: #888a8e; + border-left: 1px solid #121315 !important; + background: #363636; + margin-right: 5px; + user-select: none; + } + .el-tabs__item.is-active{ + background: #1e1e1e; + border-bottom-color: #1e1e1e!important; + color: #fff; + } + .el-icon-edit{ + color: #f1fa8c; + } + .el-icon-document{ + color: #a95812; + } +} + +// home +.right-scrollbar { + .el-scrollbar__view { + padding: 12px 18px 15px 15px; + } +} +.left-scrollbar .el-scrollbar__wrap { + box-sizing: border-box; + overflow-x: hidden !important; + margin-bottom: 0 !important; +} +.center-tabs{ + .el-tabs__header{ + margin-bottom: 0!important; + } + .el-tabs__item{ + width: 50%; + text-align: center; + } + .el-tabs__nav{ + width: 100%; + } +} +.reg-item{ + padding: 12px 6px; + background: #f8f8f8; + position: relative; + border-radius: 4px; + .close-btn{ + position: absolute; + right: -6px; + top: -6px; + display: block; + width: 16px; + height: 16px; + line-height: 16px; + background: rgba(0, 0, 0, 0.2); + border-radius: 50%; + color: #fff; + text-align: center; + z-index: 1; + cursor: pointer; + font-size: 12px; + &:hover{ + background: rgba(210, 23, 23, 0.5) + } + } + & + .reg-item{ + margin-top: 18px; + } +} +.action-bar{ + & .el-button+.el-button { + margin-left: 15px; + } + & i { + font-size: 20px; + vertical-align: middle; + position: relative; + top: -1px; + } +} + +.custom-tree-node{ + width: 100%; + font-size: 14px; + .node-operation{ + float: right; + } + i[class*="el-icon"] + i[class*="el-icon"]{ + margin-left: 6px; + } + .el-icon-plus{ + color: #409EFF; + } + .el-icon-delete{ + color: #157a0c; + } +} + +.left-scrollbar .el-scrollbar__view{ + overflow-x: hidden; +} + +.el-rate{ + display: inline-block; + vertical-align: text-top; +} +.el-upload__tip{ + line-height: 1.2; +} + +$selectedColor: #f6f7ff; +$lighterBlue: #409EFF; + +.container { + position: relative; + width: 100%; + height: 100%; +} + +.components-list { + padding: 8px; + box-sizing: border-box; + height: 100%; + .components-item { + display: inline-block; + width: 48%; + margin: 1%; + transition: transform 0ms !important; + } +} +.components-draggable{ + padding-bottom: 20px; +} +.components-title{ + font-size: 14px; + color: #222; + margin: 6px 2px; + .svg-icon{ + color: #666; + font-size: 18px; + } +} + +.components-body { + padding: 8px 10px; + background: $selectedColor; + font-size: 12px; + cursor: move; + border: 1px dashed $selectedColor; + border-radius: 3px; + .svg-icon{ + color: #777; + font-size: 15px; + } + &:hover { + border: 1px dashed #787be8; + color: #787be8; + .svg-icon { + color: #787be8; + } + } +} + +.left-board { + width: 260px; + position: absolute; + left: 0; + top: 0; + height: 100vh; +} +.left-scrollbar{ + height: calc(100vh - 42px); + overflow: hidden; +} +.center-scrollbar { + height: calc(100vh - 42px); + overflow: hidden; + border-left: 1px solid #f1e8e8; + border-right: 1px solid #f1e8e8; + box-sizing: border-box; +} +.center-board { + height: 100vh; + width: auto; + margin: 0 350px 0 260px; + box-sizing: border-box; +} +.empty-info{ + position: absolute; + top: 46%; + left: 0; + right: 0; + text-align: center; + font-size: 18px; + color: #ccb1ea; + letter-spacing: 4px; +} +.action-bar{ + position: relative; + height: 42px; + text-align: right; + padding: 0 15px; + box-sizing: border-box;; + border: 1px solid #f1e8e8; + border-top: none; + border-left: none; + .delete-btn{ + color: #F56C6C; + } +} +.logo-wrapper{ + position: relative; + height: 42px; + background: #fff; + border-bottom: 1px solid #f1e8e8; + box-sizing: border-box; +} +.logo{ + position: absolute; + left: 12px; + top: 6px; + line-height: 30px; + color: #00afff; + font-weight: 600; + font-size: 17px; + white-space: nowrap; + > img{ + width: 30px; + height: 30px; + vertical-align: top; + } + .github{ + display: inline-block; + vertical-align: sub; + margin-left: 15px; + > img{ + height: 22px; + } + } +} + +.center-board-row { + padding: 12px 12px 15px 12px; + box-sizing: border-box; + & > .el-form { + // 69 = 12+15+42 + height: calc(100vh - 69px); + } +} +.drawing-board { + height: 100%; + position: relative; + .components-body { + padding: 0; + margin: 0; + font-size: 0; + } + .sortable-ghost { + position: relative; + display: block; + overflow: hidden; + &::before { + content: " "; + position: absolute; + left: 0; + right: 0; + top: 0; + height: 3px; + background: rgb(89, 89, 223); + z-index: 2; + } + } + .components-item.sortable-ghost { + width: 100%; + height: 60px; + background-color: $selectedColor; + } + .active-from-item { + & > .el-form-item{ + background: $selectedColor; + border-radius: 6px; + } + & > .drawing-item-copy, & > .drawing-item-delete{ + display: initial; + } + & > .component-name{ + color: $lighterBlue; + } + } + .el-form-item{ + margin-bottom: 15px; + } +} +.drawing-item{ + position: relative; + cursor: move; + &.unfocus-bordered:not(.activeFromItem) > div:first-child { + border: 1px dashed #ccc; + } + .el-form-item{ + padding: 12px 10px; + } +} +.drawing-row-item{ + position: relative; + cursor: move; + box-sizing: border-box; + border: 1px dashed #ccc; + border-radius: 3px; + padding: 0 2px; + margin-bottom: 15px; + .drawing-row-item { + margin-bottom: 2px; + } + .el-col{ + margin-top: 22px; + } + .el-form-item{ + margin-bottom: 0; + } + .drag-wrapper{ + min-height: 80px; + } + &.active-from-item{ + border: 1px dashed $lighterBlue; + } + .component-name{ + position: absolute; + top: 0; + left: 0; + font-size: 12px; + color: #bbb; + display: inline-block; + padding: 0 6px; + } +} +.drawing-item, .drawing-row-item{ + &:hover { + & > .el-form-item{ + background: $selectedColor; + border-radius: 6px; + } + & > .drawing-item-copy, & > .drawing-item-delete{ + display: initial; + } + } + & > .drawing-item-copy, & > .drawing-item-delete{ + display: none; + position: absolute; + top: -10px; + width: 22px; + height: 22px; + line-height: 22px; + text-align: center; + border-radius: 50%; + font-size: 12px; + border: 1px solid; + cursor: pointer; + z-index: 1; + } + & > .drawing-item-copy{ + right: 56px; + border-color: $lighterBlue; + color: $lighterBlue; + background: #fff; + &:hover{ + background: $lighterBlue; + color: #fff; + } + } + & > .drawing-item-delete{ + right: 24px; + border-color: #F56C6C; + color: #F56C6C; + background: #fff; + &:hover{ + background: #F56C6C; + color: #fff; + } + } +} + +</style> -- Gitblit v1.9.2