<template>
|
<div class="drag-container">
|
<!-- @start="onStart" -->
|
<div class="drag-left">
|
<div class="left-title">组件列表</div>
|
<draggable
|
v-model="components"
|
@end="end1"
|
class="left-draggable-item"
|
:group="{ name: 'componentsGroup', pull: 'clone', put: false }"
|
animation="300"
|
@start="onStart"
|
:sort="false"
|
:move="onMove1"
|
>
|
<transition-group>
|
<div
|
:class="item.id == 1 ? 'item forbid' : 'item'"
|
v-for="item in components"
|
:key="item.id"
|
>
|
<i :class="item.icon"></i> {{ item.name }}
|
</div>
|
</transition-group>
|
</draggable>
|
<div class="example">
|
<div @click="example1">示例一<i class="el-icon-arrow-right"></i></div>
|
<div @click="example2">示例二<i class="el-icon-arrow-right"></i></div>
|
<div @click="example3">示例三<i class="el-icon-arrow-right"></i></div>
|
</div>
|
</div>
|
|
<div class="drag-center">
|
<div class="center-top">
|
<span>
|
<!-- <i class="el-icon-warning-outline"></i>高效的表单配置 -->
|
</span>
|
<el-button type="primary" size="mini" plain @click="save"
|
><i class="el-icon-check"> </i>保存</el-button
|
>
|
<el-button type="primary" size="mini" plain @click="preview(true)"
|
><i class="el-icon-view"> </i>预览</el-button
|
>
|
<el-button type="primary" size="mini" plain @click="download"
|
><i class="el-icon-view"> </i>下载</el-button
|
>
|
<el-button type="primary" @click="clearItems" size="mini" plain
|
><i class="el-icon-delete"> </i>清空</el-button
|
>
|
<a
|
style="margin-left: 15px"
|
href="http://v2.volcore.xyz/document/api"
|
target="_blank"
|
>设计器基于框架volform、voltable、volupload、volbox定制开发</a
|
>
|
</div>
|
<div>
|
<el-alert
|
title="关于表单设计器"
|
type="success"
|
:show-icon="true"
|
:closable="false"
|
>
|
<div>
|
1、表单设计器基于draggable开发,为本框架自定义页面功能的补充,框架仍以可视化代码生成器为核心
|
</div>
|
<div>
|
2、支持可视化设计1对1、1对多及表单下拉框自动绑定、table自动加载数据(分页、编辑)、自动上传文件、富文本编辑
|
</div>
|
</el-alert>
|
</div>
|
<el-scrollbar style="flex: 1">
|
<div class="tips" key="empty" v-show="!currentComponents.length">
|
请将左边组件拖入此容器中
|
</div>
|
<el-form label-position="top">
|
<draggable
|
class="draggable-container"
|
v-model="currentComponents"
|
@end="end2"
|
animation="300"
|
:move="onMove"
|
group="componentsGroup"
|
>
|
<transition-group class="drag-center-item">
|
<div
|
class="item2"
|
:class="{ actived: index === currentIndex }"
|
@click="itemClick(item, index)"
|
:style="{ width: item.width + '%' }"
|
v-for="(item, index) in currentComponents"
|
:key="index"
|
>
|
<i
|
class="el-icon-document-copy"
|
@click.stop="copyItem(item)"
|
></i>
|
<i class="el-icon-delete" @click.stop="removeItem(index)"> </i>
|
<el-form-item
|
:required="item.required"
|
label-position="top"
|
style="width: 100%"
|
:label="item.type == 'line' ? '' : item.name"
|
>
|
<el-col>
|
<!-- <div></div> -->
|
<!-- {{ item.name }} -->
|
<el-input
|
v-if="item.type == 'text'"
|
placeholder="请输入内容"
|
v-model="item.value"
|
:disabled="item.readonly"
|
size="medium"
|
></el-input>
|
<el-input
|
v-else-if="item.type == 'textarea'"
|
type="textarea"
|
v-model="item.value"
|
:disabled="item.readonly"
|
placeholder="请输入内容"
|
></el-input>
|
<el-date-picker
|
v-else-if="item.type == 'date'"
|
align="right"
|
v-model="item.value"
|
type="date"
|
:disabled="item.readonly"
|
size="medium"
|
placeholder="选择日期"
|
>
|
</el-date-picker>
|
<el-radio-group
|
:disabled="item.readonly"
|
v-else-if="item.type == 'radio'"
|
v-model="item.value"
|
>
|
<el-radio
|
v-for="item in item.data"
|
:key="item.key"
|
:label="item.value"
|
:value="item.key"
|
>
|
</el-radio>
|
<!-- <el-radio :label="1">是</el-radio>
|
<el-radio :label="0">否</el-radio> -->
|
</el-radio-group>
|
|
<el-checkbox-group
|
v-model="item.values"
|
:disabled="item.readonly"
|
style="width: 100%; display: inline-block"
|
v-else-if="item.type == 'checkbox'"
|
>
|
<el-checkbox
|
v-for="item in item.data"
|
:key="item.key"
|
:label="item.value"
|
:value="item.key"
|
>
|
</el-checkbox>
|
<!-- <el-checkbox label="复选框 A"></el-checkbox>
|
<el-checkbox label="复选框 B"></el-checkbox>
|
<el-checkbox label="复选框 C"></el-checkbox> -->
|
</el-checkbox-group>
|
|
<el-select
|
style="width: 100%"
|
:disabled="item.readonly"
|
v-model="item.value"
|
size="medium"
|
v-else-if="item.type == 'select'"
|
placeholder="请选择"
|
>
|
<el-option
|
v-for="item in item.data"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
<el-select
|
style="width: 100%"
|
:disabled="item.readonly"
|
v-model="item.values"
|
size="medium"
|
:multiple="true"
|
v-else-if="item.type == 'selectList'"
|
placeholder="请选择"
|
>
|
<el-option
|
v-for="item in item.data"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
<el-cascader
|
:disabled="item.readonly"
|
style="width: 100%"
|
v-else-if="item.type == 'cascader'"
|
v-model="item.values"
|
:options="item.data"
|
@change="() => {}"
|
></el-cascader>
|
|
<el-switch
|
:disabled="item.readonly"
|
v-model="item.value"
|
style="width: 100%"
|
v-else-if="item.type == 'switch'"
|
active-color="#13ce66"
|
inactive-color="#0e7ef3"
|
:active-value="1"
|
:inactive-value="0"
|
>
|
</el-switch>
|
<div class="col-line" v-else-if="item.type == 'line'">
|
{{ item.name }}
|
</div>
|
|
<vol-upload
|
v-else-if="
|
item.type == 'img' ||
|
item.type == 'excel' ||
|
item.type == 'file'
|
"
|
:fileInfo="item.fileInfo"
|
:url="item.url"
|
:img="item.type == 'img'"
|
:excel="item.type == 'excel'"
|
:multiple="item.multiple"
|
:max-size="item.maxSize"
|
:max-file="item.maxFile"
|
:autoUpload="item.autoUpload"
|
>
|
</vol-upload>
|
<vol-wang-editor
|
v-else-if="item.type == 'editor'"
|
:url="item.url"
|
v-model="item.value"
|
:height="item.height"
|
></vol-wang-editor>
|
|
<vol-table
|
v-else-if="item.type == 'table'"
|
:url="item.url"
|
:load-key="true"
|
:index="item.edit"
|
:tableData="item.tableData"
|
:columns="item.columns"
|
:height="item.height"
|
:pagination-hide="true"
|
:column-index="item.columnIndex"
|
:ck="item.ck"
|
></vol-table>
|
<el-button
|
@click="model = true"
|
v-else-if="item.type == 'box'"
|
type="primary"
|
size="small"
|
>{{ item.name }}</el-button
|
>
|
</el-col>
|
</el-form-item>
|
</div>
|
</transition-group>
|
</draggable>
|
</el-form>
|
</el-scrollbar>
|
</div>
|
<div class="drag-right">
|
<div class="left-title">组件属性</div>
|
<div class="attr" v-show="currentIndex != -1">
|
<div class="attr-item">
|
<div class="text">字段名称</div>
|
<el-input size="medium" v-model="currentItem.name" />
|
</div>
|
<div class="attr-item">
|
<div class="text">字段(唯一字段)</div>
|
<el-input size="medium" v-model="currentItem.field" />
|
</div>
|
<div class="attr-item" v-show="currentItem.type == 'table'">
|
<div class="text">后台返回数据接口地址</div>
|
<el-input
|
size="medium"
|
placeholder="例:api/表名/getPageData"
|
v-model="currentItem.url"
|
/>
|
</div>
|
<div
|
class="attr-item"
|
v-show="
|
currentItem.type != 'table' && currentItem.hasOwnProperty('url')
|
"
|
>
|
<div class="text">上传接口地址(后台接口)</div>
|
<el-input
|
size="medium"
|
placeholder="可用框架地址:api/表名/upload"
|
v-model="currentItem.url"
|
/>
|
<div class="text" style="margin-top: 10px">文件大小限制(M)</div>
|
<el-input size="medium" v-model="currentItem.maxSize" />
|
<div class="text" style="margin-top: 10px">是否多文件上传</div>
|
<el-switch
|
v-model="currentItem.multiple"
|
style="width: 100%"
|
active-color="#13ce66"
|
inactive-color="rgb(165 165 165)"
|
:active-value="true"
|
:inactive-value="false"
|
>
|
</el-switch>
|
<div class="text" style="margin-top: 10px">是否自动上传</div>
|
<el-switch
|
v-model="currentItem.autoUpload"
|
style="width: 100%"
|
active-color="#13ce66"
|
inactive-color="rgb(165 165 165)"
|
:active-value="true"
|
:inactive-value="false"
|
>
|
</el-switch>
|
</div>
|
<div class="attr-item" v-show="currentItem.data">
|
<div class="text">数据源(下拉框绑定设置中维护)</div>
|
|
<!-- dicList -->
|
<el-select
|
style="width: 100%"
|
v-model="currentItem.key"
|
size="medium"
|
@change="dicChange"
|
placeholder="请选择数据源字典"
|
>
|
<el-option
|
v-for="item in dicList"
|
:key="item.key"
|
:label="item.value"
|
:value="item.key"
|
>
|
</el-option>
|
</el-select>
|
</div>
|
<div class="attr-item" v-show="currentItem.type != 'table'">
|
<div class="text">标签宽度</div>
|
<el-slider
|
style="width: 90%"
|
:min="20"
|
v-model="colWidth"
|
:step="10"
|
show-stops
|
>
|
</el-slider>
|
</div>
|
<div class="attr-item attr2" v-show="currentItem.type != 'table'">
|
<div>
|
<div class="text">必填</div>
|
<el-switch
|
v-model="currentItem.required"
|
style="width: 100%"
|
active-color="#13ce66"
|
inactive-color="rgb(165 165 165)"
|
:active-value="true"
|
:inactive-value="false"
|
>
|
</el-switch>
|
</div>
|
|
<div>
|
<!-- active-text="是"
|
inactive-text="否" -->
|
<div class="text">只读</div>
|
<el-switch
|
v-model="currentItem.readonly"
|
style="width: 100%"
|
active-color="#13ce66"
|
inactive-color="rgb(165 165 165)"
|
:active-value="true"
|
:inactive-value="false"
|
>
|
</el-switch>
|
</div>
|
</div>
|
<div v-show="currentItem.type == 'table'">
|
<div class="attr-item">
|
<div class="text">是否使用选项卡(tabs)</div>
|
<div>
|
<el-switch
|
v-model="currentItem.tabs"
|
style="width: 100%"
|
active-text="是"
|
inactive-text="否"
|
active-color="#13ce66"
|
inactive-color="rgb(165 165 165)"
|
:active-value="true"
|
:inactive-value="false"
|
>
|
</el-switch>
|
</div>
|
</div>
|
<div class="attr-item attr2">
|
<el-button
|
style="width: 100%"
|
@click="openTableModel"
|
type="primary"
|
size="medium"
|
>table配置</el-button
|
>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<vol-box
|
v-model="model"
|
:height="300"
|
:width="550"
|
:lazy="true"
|
title="弹出框"
|
>
|
<template #content>
|
<div>弹出框内容</div>
|
</template>
|
<template #footer>
|
<div>
|
<el-button type="primary" size="mini" @click="model = false"
|
><i class="el-icon-close"></i>点击关闭</el-button
|
>
|
<el-button size="mini" @click="model = false"
|
><i class="el-icon-close"></i>关闭</el-button
|
>
|
</div>
|
</template>
|
</vol-box>
|
|
<vol-box
|
v-model="previewModel"
|
:height="600"
|
:width="1300"
|
:lazy="true"
|
:padding="1"
|
:close="false"
|
title="预览"
|
>
|
<preview style="height:600px" :options="viewFormData"></preview>
|
</vol-box>
|
|
<vol-box
|
v-model="tableModel"
|
:height="600"
|
:width="1300"
|
:lazy="true"
|
:padding="0"
|
:title="currentItem.name"
|
>
|
<template #content>
|
<div style="height:600px" >
|
<el-alert title="关于table配置" type="info" :closable="false" show-icon>
|
此处table是对框架voltable基本操作的配置,如果需要事件触发、数据加载等更多功能,请在生成后的代码添加需要的功能,完整配置见文档<a
|
href="http://v2.volcore.xyz/document/api"
|
style="color: #1e88e5; margin-left: 9px"
|
target="_blank"
|
>voltable</a
|
>
|
</el-alert>
|
<div class="btns">
|
<div class="btns-left">
|
表格默认功能按钮:
|
<el-checkbox
|
v-for="item in currentItem.buttons"
|
:label="item.name"
|
:key="item.name"
|
>{{ item.name }}</el-checkbox
|
>
|
</div>
|
<div class="btns-right">
|
<el-button type="primary" size="mini" @click="addRow"
|
><i class="el-icon-plus"></i>添加字段</el-button
|
>
|
<el-button type="primary" size="mini" @click="delRow"
|
><i class="el-icon-delete"></i>删除字段</el-button
|
>
|
<el-button type="primary" size="mini" @click="sortRow"
|
><i class="el-icon-sort"></i>重新排列</el-button
|
>
|
</div>
|
</div>
|
<vol-table
|
:load-key="true"
|
:tableData="currnetTableData"
|
:columns="currentTableOption"
|
:height="448"
|
ref="table"
|
:index="true"
|
:pagination-hide="true"
|
:column-index="true"
|
:ck="true"
|
></vol-table>
|
</div>
|
</template>
|
<template #footer>
|
<div style="text-align: center">
|
<el-button size="mini" @click="tableModel = false"
|
><i class="el-icon-close"></i>关闭</el-button
|
>
|
<el-button type="primary" size="mini" @click="saveConfigOptions"
|
><i class="el-icon-check"></i>保存</el-button
|
>
|
</div>
|
</template>
|
</vol-box>
|
</template>
|
|
<script>
|
import { h, resolveComponent } from "vue";
|
// import draggable from "vuedraggable";
|
import { VueDraggableNext } from "vue-draggable-next";
|
import VolWangEditor from "@/components/editor/VolWangEditor.vue";
|
import VolUpload from "./../VolUpload";
|
import VolTable from "./../VolTable";
|
import VolBox from "./../VolBox";
|
import VolFormPreview from "./VolFormPreview";
|
import { components, tableOption } from "./options";
|
import { options1, options2, options3 } from "./formTemplate";
|
import downloadForm from "./DownloadForm";
|
export default {
|
props: {
|
userComponents: {
|
type: Array,
|
default: () => {
|
return [];
|
},
|
},
|
},
|
components: {
|
draggable: VueDraggableNext,
|
"vol-upload": VolUpload,
|
"vol-wang-editor": VolWangEditor,
|
"vol-table": VolTable,
|
"vol-box": VolBox,
|
preview: VolFormPreview,
|
},
|
data() {
|
return {
|
options:{},
|
options1: options1,
|
options2: options2,
|
options3: options3,
|
colWidth: 100,
|
currentIndex: -1,
|
currentItem: {},
|
currnetTableData: [],
|
currentTableOption: tableOption,
|
//定义要被拖拽对象的数组
|
components: components,
|
currentComponents: [],
|
dicList: [],
|
model: false,
|
tableModel: false,
|
previewModel: false,
|
viewFormData: { fields: {}, formOptions: [], tables: [] },
|
};
|
},
|
watch: {
|
colWidth(newVal) {
|
if (this.currentIndex != -1) {
|
this.currentComponents[this.currentIndex].width = newVal;
|
}
|
},
|
userComponents: {
|
handler(newVal) {
|
this.currentComponents = newVal;
|
},
|
immediate: true,
|
deep: true,
|
},
|
},
|
created() {
|
this.currentComponents = this.userComponents;
|
this.http
|
.post("api/Sys_Dictionary/GetBuilderDictionary", {}, false)
|
.then((x) => {
|
this.dicList = x.map((c) => {
|
return { key: c, value: c };
|
});
|
});
|
},
|
methods: {
|
getFormOptions(item) {
|
let _option = {};
|
_option.field = item.field;
|
_option.title = item.name;
|
_option.type = item.type;
|
_option.required = item.required;
|
_option.readonly = item.readonly;
|
if (item.type == "line") {
|
_option.title = "";
|
let title = item.name;
|
_option.render = (h) => {
|
return h(
|
"div",
|
{
|
style: {
|
"line-height": "25px",
|
"font-weight": "bold",
|
"margin-left": "15px",
|
"border-bottom": "1px solid #dadada",
|
},
|
},
|
title
|
//也可以在这里放一些组件,例如:
|
// resolveComponent("el-tooltip"),
|
// {
|
// content: "这里是提示的内容",
|
// props: { effect: "dark", placement: "top-start" },
|
// style: {},
|
// },
|
// [h("a", { style: { color: "#2a92ff" } }, "提示信息")]
|
);
|
};
|
}
|
if (item.type == "editor") {
|
_option.height = item.height;
|
}
|
if (item.width == 100) {
|
_option.colSize = 12;
|
} else {
|
_option.colSize = (_option.width * 12) / 100;
|
}
|
if (["img", "excel", "file"].indexOf(item.type) != -1) {
|
_option.maxSize = item.maxSize;
|
_option.fileInfo = item.fileInfo;
|
_option.multiple = item.multiple;
|
_option.autoUpload = item.autoUpload;
|
_option.maxFile = item.maxFile;
|
}
|
if (
|
["img", "excel", "file", "editor", "table"].indexOf(item.type) != -1
|
) {
|
_option.url = item.url;
|
}
|
if (item.data) {
|
_option.data = item.data;
|
_option.dataKey = item.key;
|
}
|
return _option;
|
},
|
getLineFormOptions(index) {
|
let _index = index;
|
let endIndex = index;
|
let width = 0;
|
let _options = [];
|
for (index; index < this.filterCurrentComponents().length; index++) {
|
const item = this.currentComponents[index];
|
if (item.width + width <= 100) {
|
width = item.width + width;
|
endIndex = index;
|
_options.push(this.getFormOptions(item));
|
}
|
}
|
return { options: _options, index: _index, endIndex: endIndex };
|
},
|
filterCurrentComponents() {
|
return this.currentComponents.filter((x) => {
|
return x.type != "table";
|
});
|
},
|
setSpan() {},
|
preview(isPre) {
|
let _fields = {};
|
let _formOptions = [];
|
let endIndex = -1;
|
this.filterCurrentComponents().forEach((item, index) => {
|
if (item.hasOwnProperty("values")) {
|
_fields[item.field] = [];
|
} else {
|
_fields[item.field] = null;
|
}
|
|
if (item.width == 100) {
|
_formOptions.push([this.getFormOptions(item)]);
|
} else {
|
if (endIndex == -1) {
|
let lineOptions = this.getLineFormOptions(index);
|
endIndex = lineOptions.endIndex;
|
_formOptions.push(lineOptions.options);
|
endIndex--;
|
} else {
|
endIndex--;
|
}
|
}
|
// _fields[item.field] = null;xc
|
// let _option = {};
|
// _option.field = item.field;
|
// _option.title = item.name;
|
// _option.type = item.type;
|
// _option.required = item.required;
|
// _option.readonly = item.readonly;
|
// if (["img", "excel", "file"].indexOf(item.type) != -1) {
|
// _option.maxSize = item.maxSize;
|
// _option.fileInfo = item.fileInfo;
|
// _option.multiple = item.multiple;
|
// _option.autoUpload = item.autoUpload;
|
// _option.maxFile = item.maxFile;
|
// }
|
// if (
|
// ["img", "excel", "file", "editor", "table"].indexOf(item.type) != -1
|
// ) {
|
// _option.url = item.url;
|
// }
|
// if (item.data) {
|
// _option.data = item.data;
|
// _option.dataKey = item.key;
|
// }
|
// _formOptions.push(_option);
|
});
|
this.viewFormData.fields = _fields;
|
// console.log(JSON.stringify(_formOptions))
|
this.viewFormData.formOptions = _formOptions;
|
if (isPre) {
|
this.previewModel = true;
|
}
|
let tableIndex = 0;
|
let keys = [];
|
let tables = this.currentComponents
|
.filter((x) => {
|
return x.type == "table";
|
})
|
.map((m) => {
|
m.pagination = !m.url;
|
if (m.name == "表格") {
|
tableIndex++;
|
}
|
return {
|
name: m.name + (m.name == "表格" ? tableIndex : ""),
|
url: m.url,
|
tabs: m.tabs,
|
pagination: m.pagination,
|
buttons: m.buttons,
|
columns: m.columns.map((c) => {
|
let obj = {
|
title: c.title,
|
field: c.field,
|
hidden: !c.show,
|
width: c.width,
|
required: c.required,
|
};
|
|
if (c.dataSource) {
|
obj.bind = { key: c.dataSource, data: [] };
|
}
|
if (c.dataSource) {
|
keys.push(c.dataSource);
|
}
|
if (c.edit) {
|
if (!obj.bind) {
|
obj.bind = { key: "", data: [] };
|
}
|
obj.edit = { type: c.editType };
|
}
|
return obj;
|
}),
|
tableData: [{}, {}, {}],
|
};
|
});
|
this.viewFormData.tables = tables.filter((x) => {
|
return !x.tabs;
|
});
|
this.viewFormData.tabs = tables.filter((x) => {
|
return x.tabs;
|
});
|
this.getDicKeys(keys);
|
this.options = this.viewFormData;
|
},
|
getDicKeys(keys) {
|
if (!keys.length) {
|
return;
|
}
|
debugger
|
this.http
|
.post("api/Sys_Dictionary/GetVueDictionary", keys, true)
|
.then((result) => {
|
result.forEach((c) => {
|
this.viewFormData.tables.forEach((t) => {
|
let _option = t.columns.find((x) => {
|
return x.bind && x.bind.key == c.dicNo;
|
});
|
if (_option) {
|
_option.bind.data = c.data;
|
}
|
});
|
this.viewFormData.tabs.forEach((t) => {
|
let _option = t.columns.find((x) => {
|
return x.bind && x.bind.key == c.dicNo;
|
});
|
if (_option) {
|
_option.bind.data = c.data;
|
}
|
});
|
});
|
});
|
},
|
save() {
|
this.preview(false);
|
this.$emit("save", {
|
daraggeOptions: this.currentComponents,
|
formOptions: this.viewFormData,
|
});
|
},
|
download() {
|
this.preview(false);
|
downloadForm.call(this);
|
},
|
openTableModel() {
|
let dataSource = this.currentTableOption.find((x) => {
|
return x.field == "dataSource";
|
});
|
if (!dataSource.bind.data.length) {
|
dataSource.bind.data = this.dicList;
|
}
|
this.currnetTableData = JSON.parse(
|
JSON.stringify(this.currentItem.columns)
|
);
|
this.tableModel = true;
|
},
|
addRow() {
|
this.currnetTableData.push({ field: this.getField() });
|
},
|
delRow() {
|
this.$confirm("确认要删除选择的数据吗?", "警告", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
center: true,
|
}).then(() => {
|
this.$refs.table.delRow();
|
});
|
},
|
sortRow() {
|
this.currnetTableData = this.currnetTableData.sort((a, b) => {
|
return a.orderNo - b.orderNo;
|
}); //.reverse();
|
this.$Message.success("列显示顺序已重新排列,点击预览可查看");
|
},
|
saveConfigOptions() {
|
this.currentItem.columns = JSON.parse(
|
JSON.stringify(this.currnetTableData)
|
);
|
this.tableModel = false;
|
},
|
copyItem(item) {
|
let itemClone = JSON.parse(JSON.stringify(item));
|
itemClone.field = "field" + new Date().valueOf();
|
this.currentComponents.push(itemClone);
|
},
|
removeItem(index) {
|
this.currentComponents.splice(index, 1);
|
this.colWidth = 100;
|
this.currentIndex = -1;
|
this.currentItem = {};
|
},
|
clearItems() {
|
this.currentComponents.length = 0;
|
this.colWidth = 100;
|
this.currentIndex = -1;
|
this.currentItem = {};
|
},
|
itemClick(item, index) {
|
this.currentIndex = index;
|
this.colWidth = this.currentComponents[this.currentIndex].width;
|
this.currentItem = this.currentComponents[this.currentIndex];
|
},
|
//开始拖拽事件
|
onStart(e, e1) {
|
this.drag = true;
|
},
|
getField() {
|
return "field" + new Date().valueOf();
|
},
|
//左边往右边拖动时的事件
|
end1(e) {
|
if (1 == 1 && e.from !== e.to) {
|
let obj = JSON.parse(JSON.stringify(this.components[e.oldIndex]));
|
obj.field = this.getField();
|
obj.width = 100;
|
obj.readonly = false;
|
obj.required = false;
|
this.currentComponents.splice(e.newIndex, 1, obj);
|
this.userComponents.splice(0);
|
this.userComponents.push(...this.currentComponents);
|
// this.currentComponents = this.currentComponents.filter((x) => {
|
// return x.hasOwnProperty("field");
|
// });
|
this.colWidth = 100;
|
this.currentIndex = e.newIndex; //this.currentComponents.length - 1;
|
this.currentItem = this.currentComponents[this.currentIndex];
|
}
|
},
|
//右边往左边拖动时的事件
|
end2(e) {},
|
onMove1(e, originalEvent) {
|
// this.moveId = e.relatedContext.element.id;
|
return true;
|
},
|
//move回调方法
|
onMove(e, originalEvent) {
|
console.log(JSON.stringify(this.currentComponents));
|
return true;
|
},
|
dicChange(key) {
|
debugger
|
this.http
|
.post("api/Sys_Dictionary/GetVueDictionary", [key], true)
|
.then((result) => {
|
this.currentItem.data = result[0].data;
|
if (result[0].data.length) {
|
if (this.currentItem.type == "select") {
|
this.currentItem.value = result[0].data[0].value;
|
} else {
|
this.currentItem.values = [result[0].data[0].value];
|
}
|
}
|
});
|
},
|
example1() {
|
this.currentComponents = this.options1;
|
},
|
example2() {
|
this.currentComponents = this.options2;
|
},
|
example3() {
|
this.currentComponents = this.options3;
|
},
|
},
|
computed: {
|
tabsTable() {
|
return this.currentComponents.filter((x) => {
|
return x.type == "table" && x.tabs == true;
|
});
|
},
|
},
|
};
|
</script>
|
<style lang="less" scoped>
|
* {
|
box-sizing: border-box;
|
}
|
.drag-container {
|
/* padding: 20px; */
|
display: flex;
|
height: 100%;
|
position: absolute;
|
width: 100%;
|
box-sizing: border-box;
|
}
|
.drag-left {
|
width: 250px;
|
display: flex;
|
border-right: 1px solid #eee;
|
flex-direction: column;
|
}
|
.left-title {
|
height: 42px;
|
text-align: left;
|
border-right: 1px solid #eee;
|
padding: 10px 0 10px 11px;
|
border-bottom: 1px solid #eee;
|
}
|
.drag-center {
|
display: flex;
|
flex-direction: column;
|
flex: 1;
|
}
|
.left-draggable-item {
|
// flex: 1;
|
display: inline-block;
|
padding: 5px;
|
// border-right: 1px solid #eee;
|
}
|
|
.left-draggable-item .item {
|
cursor: move;
|
float: left;
|
width: 111px;
|
/* height: 20px; */
|
text-align: center;
|
border: 1px solid #eeeeee;
|
padding: 2px 13px;
|
text-align: left;
|
line-height: 28px;
|
margin: 4px;
|
border-radius: 3px;
|
background: #f0f9eb;
|
font-size: 13px;
|
}
|
// .drag-center-item {
|
// display: inline-block;
|
// width: 100%;
|
// height: calc(100vh - 122px);
|
// padding: 10px;
|
// }
|
.draggable-container {
|
display: inline-block;
|
width: 100%;
|
height: calc(100vh - 215px);
|
padding: 10px 0;
|
}
|
|
.item2 {
|
position: relative;
|
cursor: move;
|
padding: 18px 10px 10px 10px;
|
text-align: left;
|
float: left;
|
margin-bottom: 10px;
|
}
|
.item2 .el-icon-delete,
|
.item2 .el-icon-document-copy {
|
position: absolute;
|
right: 10px;
|
top: 2px;
|
padding: 5px;
|
display: none;
|
color: red;
|
cursor: pointer;
|
}
|
.item2 .el-icon-document-copy {
|
right: 35px;
|
}
|
.item2:hover,
|
.actived {
|
background: #f0f9eb;
|
}
|
.item:hover {
|
border: 1px dashed #787be8;
|
color: #787be8;
|
}
|
.item2:hover .el-icon-delete,
|
.item2:hover .el-icon-document-copy {
|
display: block;
|
}
|
|
.drag-right {
|
background: #f7fbff3d;
|
width: 250px;
|
border-left: 1px solid #eee;
|
}
|
|
.center-top {
|
height: 42px;
|
line-height: 41px;
|
background: #f2f5fb;
|
border-bottom: 1px solid #eee;
|
text-align: left;
|
padding: 0 10px;
|
font-size: 12px;
|
color: #3391f3;
|
}
|
.center-top span {
|
margin-right: 10px;
|
}
|
.attr {
|
padding: 0px 15px 15px 15px;
|
}
|
.attr-item {
|
text-align: left;
|
margin-top: 12px;
|
font-size: 14px;
|
}
|
.attr-item .text {
|
padding: 0 0 5px 5px;
|
}
|
.attr2 {
|
display: flex;
|
}
|
.attr2 > div {
|
flex: 1;
|
}
|
.tips {
|
position: absolute;
|
font-size: 26px;
|
letter-spacing: 6px;
|
left: 0px;
|
right: 0px;
|
top: 150px;
|
width: 500px;
|
margin: auto;
|
color: #c5c5c5;
|
}
|
.col-line {
|
line-height: 25px;
|
font-weight: bold;
|
border-bottom: 1px solid rgb(218 218 218);
|
}
|
.drag-container ::v-deep(.el-col) {
|
width: 100%;
|
}
|
.drag-center ::v-deep(.el-form-item__label) {
|
line-height: 0 !important;
|
}
|
.drag-center ::v-deep(.el-scrollbar__wrap) {
|
overflow-x: hidden;
|
}
|
.drag-center ::v-deep(.el-form-item) {
|
margin-bottom: 10px;
|
}
|
.drag-center ::v-deep(.el-date-editor) {
|
width: 100%;
|
}
|
.drag-center ::v-deep(.el-checkbox) {
|
margin-right: 15px;
|
}
|
.drag-center ::v-deep(.el-checkbox__label) {
|
padding-left: 5px;
|
}
|
.drag-center ::v-deep(.hello > div) {
|
z-index: 500 !important;
|
}
|
.drag-center ::v-deep(th),
|
.drag-center ::v-deep(td) {
|
padding: 6px 0;
|
}
|
.example {
|
margin-top: 8px;
|
> div {
|
cursor: pointer;
|
padding: 14px 20px;
|
border-top: 1px solid #eee;
|
font-size: 13px;
|
color: #646465;
|
position: relative;
|
}
|
> div:hover {
|
background: rgb(231, 231, 231);
|
}
|
i {
|
position: absolute;
|
right: 20px;
|
}
|
}
|
.btns {
|
padding: 8px 0;
|
display: flex;
|
> div {
|
flex: 1;
|
}
|
.btns-left {
|
padding-top: 8px;
|
color: black;
|
font-weight: bold;
|
}
|
.btns-right {
|
text-align: right;
|
}
|
}
|
</style>
|