right panel
This commit is contained in:
10
jsconfig.json
Normal file
10
jsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// ...
|
||||||
|
"types": ["element-plus/global"],
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
95
public/preview.html
Normal file
95
public/preview.html
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title>form-generator-preview</title>
|
||||||
|
<link href="https://unpkg.com/browse/element-plus@2.2.26/dist/index.css" rel="stylesheet">
|
||||||
|
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
||||||
|
<script src="https://unpkg.com/browse/vue-router@4.1.6/dist/vue-router.global.prod.js"></script>
|
||||||
|
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/browse/element-plus@2.2.26/dist/index.full.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
height: calc(100vh - 33px);
|
||||||
|
padding: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>抱歉,javascript被禁用,请开启后重试。</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="previewApp"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
Vue.prototype.$axios = axios
|
||||||
|
const childAttrs = {
|
||||||
|
file: '',
|
||||||
|
dialog: ' width="600px" class="dialog-width" v-if="visible" :visible.sync="visible" :modal-append-to-body="false" '
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('message', init, false)
|
||||||
|
function init(event) {
|
||||||
|
if (event.data.type === 'refreshFrame') {
|
||||||
|
const code = event.data.data
|
||||||
|
const attrs = childAttrs[code.generateConf.type]
|
||||||
|
let links = ''
|
||||||
|
|
||||||
|
if (Array.isArray(code.links) && code.links.length > 0) {
|
||||||
|
links = buildLinks(code.links)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('previewApp').innerHTML = `${links}<style>${code.css}</style><div id="app"></div>`
|
||||||
|
|
||||||
|
if (Array.isArray(code.scripts) && code.scripts.length > 0) {
|
||||||
|
this.loadScriptQueue(code.scripts, () => {
|
||||||
|
newVue(attrs, code.js, code.html)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
newVue(attrs, code.js, code.html)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function buildLinks(links) {
|
||||||
|
let strs = ''
|
||||||
|
links.forEach(url => {
|
||||||
|
strs += `<link href="${url}" rel="stylesheet">`
|
||||||
|
})
|
||||||
|
return strs
|
||||||
|
}
|
||||||
|
function newVue(attrs, main, html) {
|
||||||
|
main = eval(`(${main})`)
|
||||||
|
main.template = `<div>${html}</div>`
|
||||||
|
new Vue({
|
||||||
|
components: {
|
||||||
|
child: main
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `<div><child ${attrs}/></div>`
|
||||||
|
}).$mount('#app')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -44,23 +44,51 @@
|
|||||||
border-bottom: $color-border-style;
|
border-bottom: $color-border-style;
|
||||||
border-left: $transparent-border-style;
|
border-left: $transparent-border-style;
|
||||||
border-right: $transparent-border-style;
|
border-right: $transparent-border-style;
|
||||||
}
|
} @else if $direction==right {
|
||||||
|
|
||||||
@else if $direction==right {
|
|
||||||
border-left: $color-border-style;
|
border-left: $color-border-style;
|
||||||
border-top: $transparent-border-style;
|
border-top: $transparent-border-style;
|
||||||
border-bottom: $transparent-border-style;
|
border-bottom: $transparent-border-style;
|
||||||
}
|
} @else if $direction==down {
|
||||||
|
|
||||||
@else if $direction==down {
|
|
||||||
border-top: $color-border-style;
|
border-top: $color-border-style;
|
||||||
border-left: $transparent-border-style;
|
border-left: $transparent-border-style;
|
||||||
border-right: $transparent-border-style;
|
border-right: $transparent-border-style;
|
||||||
}
|
} @else if $direction==left {
|
||||||
|
|
||||||
@else if $direction==left {
|
|
||||||
border-right: $color-border-style;
|
border-right: $color-border-style;
|
||||||
border-top: $transparent-border-style;
|
border-top: $transparent-border-style;
|
||||||
border-bottom: $transparent-border-style;
|
border-bottom: $transparent-border-style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin action-bar {
|
||||||
|
.action-bar {
|
||||||
|
height: 33px;
|
||||||
|
background: #f2fafb;
|
||||||
|
padding: 0 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.bar-btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 6px;
|
||||||
|
line-height: 32px;
|
||||||
|
color: #8285f5;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
user-select: none;
|
||||||
|
& i {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
color: #4348d4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bar-btn + .bar-btn {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
.delete-btn {
|
||||||
|
color: #f56c6c;
|
||||||
|
&:hover {
|
||||||
|
color: #ea0b30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -290,10 +290,12 @@ export const selectComponents = [
|
|||||||
{
|
{
|
||||||
label: "选项一",
|
label: "选项一",
|
||||||
value: 1,
|
value: 1,
|
||||||
|
disabled: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "选项二",
|
label: "选项二",
|
||||||
value: 2,
|
value: 2,
|
||||||
|
disabled: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -554,7 +556,7 @@ export const layoutComponents = [
|
|||||||
default: "主要按钮",
|
default: "主要按钮",
|
||||||
},
|
},
|
||||||
type: "primary",
|
type: "primary",
|
||||||
icon: "el-icon-search",
|
icon: "search",
|
||||||
round: false,
|
round: false,
|
||||||
size: "default",
|
size: "default",
|
||||||
plain: false,
|
plain: false,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
import ruleTrigger from './ruleTrigger'
|
import ruleTrigger from "./ruleTrigger";
|
||||||
|
|
||||||
let confGlobal
|
let confGlobal;
|
||||||
let someSpanIsNot24
|
let someSpanIsNot24;
|
||||||
|
|
||||||
export function dialogWrapper(str) {
|
export function dialogWrapper(str) {
|
||||||
return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Title">
|
return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Title">
|
||||||
@ -11,7 +11,7 @@ export function dialogWrapper(str) {
|
|||||||
<el-button @click="close">取消</el-button>
|
<el-button @click="close">取消</el-button>
|
||||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>`
|
</el-dialog>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function vueTemplate(str) {
|
export function vueTemplate(str) {
|
||||||
@ -19,53 +19,57 @@ export function vueTemplate(str) {
|
|||||||
<div>
|
<div>
|
||||||
${str}
|
${str}
|
||||||
</div>
|
</div>
|
||||||
</template>`
|
</template>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function vueScript(str) {
|
export function vueScript(str, isSetup) {
|
||||||
return `<script>
|
return `<script ${isSetup ? "setup" : ""}>
|
||||||
${str}
|
${str}
|
||||||
</script>`
|
</script>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cssStyle(cssStr) {
|
export function cssStyle(cssStr) {
|
||||||
return `<style>
|
return `<style>
|
||||||
${cssStr}
|
${cssStr}
|
||||||
</style>`
|
</style>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildFormTemplate(scheme, child, type) {
|
function buildFormTemplate(scheme, child, type) {
|
||||||
let labelPosition = ''
|
let labelPosition = "";
|
||||||
if (scheme.labelPosition !== 'right') {
|
if (scheme.labelPosition !== "right") {
|
||||||
labelPosition = `label-position="${scheme.labelPosition}"`
|
labelPosition = `label-position="${scheme.labelPosition}"`;
|
||||||
}
|
}
|
||||||
const disabled = scheme.disabled ? `:disabled="${scheme.disabled}"` : ''
|
const disabled = scheme.disabled ? `:disabled="${scheme.disabled}"` : "";
|
||||||
let str = `<el-form ref="${scheme.formRef}" :model="${scheme.formModel}" :rules="${scheme.formRules}" size="${scheme.size}" ${disabled} label-width="${scheme.labelWidth}px" ${labelPosition}>
|
let str = `<el-form ref="${scheme.formRef}" :model="${
|
||||||
|
scheme.formModel
|
||||||
|
}" :rules="${scheme.formRules}" size="${
|
||||||
|
scheme.size
|
||||||
|
}" ${disabled} label-width="${scheme.labelWidth}px" ${labelPosition}>
|
||||||
${child}
|
${child}
|
||||||
${buildFromBtns(scheme, type)}
|
${buildFromBtns(scheme, type)}
|
||||||
</el-form>`
|
</el-form>`;
|
||||||
if (someSpanIsNot24) {
|
if (someSpanIsNot24) {
|
||||||
str = `<el-row :gutter="${scheme.gutter}">
|
str = `<el-row :gutter="${scheme.gutter}">
|
||||||
${str}
|
${str}
|
||||||
</el-row>`
|
</el-row>`;
|
||||||
}
|
}
|
||||||
return str
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildFromBtns(scheme, type) {
|
function buildFromBtns(scheme, type) {
|
||||||
let str = ''
|
let str = "";
|
||||||
if (scheme.formBtns && type === 'file') {
|
if (scheme.formBtns && type === "file") {
|
||||||
str = `<el-form-item size="large">
|
str = `<el-form-item size="large">
|
||||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||||
<el-button @click="resetForm">重置</el-button>
|
<el-button @click="resetForm">重置</el-button>
|
||||||
</el-form-item>`
|
</el-form-item>`;
|
||||||
if (someSpanIsNot24) {
|
if (someSpanIsNot24) {
|
||||||
str = `<el-col :span="24">
|
str = `<el-col :span="24">
|
||||||
${str}
|
${str}
|
||||||
</el-col>`
|
</el-col>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return str
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// span不为24的用el-col包裹
|
// span不为24的用el-col包裹
|
||||||
@ -73,304 +77,360 @@ function colWrapper(scheme, str) {
|
|||||||
if (someSpanIsNot24 || scheme.__config__.span !== 24) {
|
if (someSpanIsNot24 || scheme.__config__.span !== 24) {
|
||||||
return `<el-col :span="${scheme.__config__.span}">
|
return `<el-col :span="${scheme.__config__.span}">
|
||||||
${str}
|
${str}
|
||||||
</el-col>`
|
</el-col>`;
|
||||||
}
|
}
|
||||||
return str
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
const layouts = {
|
const layouts = {
|
||||||
colFormItem(scheme) {
|
colFormItem(scheme) {
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
let labelWidth = ''
|
let labelWidth = "";
|
||||||
let label = `label="${config.label}"`
|
let label = `label="${config.label}"`;
|
||||||
if (config.labelWidth && config.labelWidth !== confGlobal.labelWidth) {
|
if (config.labelWidth && config.labelWidth !== confGlobal.labelWidth) {
|
||||||
labelWidth = `label-width="${config.labelWidth}px"`
|
labelWidth = `label-width="${config.labelWidth}px"`;
|
||||||
}
|
}
|
||||||
if (config.showLabel === false) {
|
if (config.showLabel === false) {
|
||||||
labelWidth = 'label-width="0"'
|
labelWidth = 'label-width="0"';
|
||||||
label = ''
|
label = "";
|
||||||
}
|
}
|
||||||
const required = !ruleTrigger[config.tag] && config.required ? 'required' : ''
|
const required =
|
||||||
const tagDom = tags[config.tag] ? tags[config.tag](scheme) : null
|
!ruleTrigger[config.tag] && config.required ? "required" : "";
|
||||||
|
const tagDom = tags[config.tag] ? tags[config.tag](scheme) : null;
|
||||||
let str = `<el-form-item ${labelWidth} ${label} prop="${scheme.__vModel__}" ${required}>
|
let str = `<el-form-item ${labelWidth} ${label} prop="${scheme.__vModel__}" ${required}>
|
||||||
${tagDom}
|
${tagDom}
|
||||||
</el-form-item>`
|
</el-form-item>`;
|
||||||
str = colWrapper(scheme, str)
|
str = colWrapper(scheme, str);
|
||||||
return str
|
return str;
|
||||||
},
|
},
|
||||||
rowFormItem(scheme) {
|
rowFormItem(scheme) {
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
const type = scheme.type === 'default' ? '' : `type="${scheme.type}"`
|
const type = scheme.type === "default" ? "" : `type="${scheme.type}"`;
|
||||||
const justify = scheme.type === 'default' ? '' : `justify="${scheme.justify}"`
|
const justify =
|
||||||
const align = scheme.type === 'default' ? '' : `align="${scheme.align}"`
|
scheme.type === "default" ? "" : `justify="${scheme.justify}"`;
|
||||||
const gutter = scheme.gutter ? `:gutter="${scheme.gutter}"` : ''
|
const align = scheme.type === "default" ? "" : `align="${scheme.align}"`;
|
||||||
const children = config.children.map(el => layouts[el.__config__.layout](el))
|
const gutter = scheme.gutter ? `:gutter="${scheme.gutter}"` : "";
|
||||||
|
const children = config.children.map((el) =>
|
||||||
|
layouts[el.__config__.layout](el)
|
||||||
|
);
|
||||||
let str = `<el-row ${type} ${justify} ${align} ${gutter}>
|
let str = `<el-row ${type} ${justify} ${align} ${gutter}>
|
||||||
${children.join('\n')}
|
${children.join("\n")}
|
||||||
</el-row>`
|
</el-row>`;
|
||||||
str = colWrapper(scheme, str)
|
str = colWrapper(scheme, str);
|
||||||
return str
|
return str;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const tags = {
|
const tags = {
|
||||||
'el-button': el => {
|
"el-button": (el) => {
|
||||||
const {
|
const { tag, disabled } = attrBuilder(el);
|
||||||
tag, disabled
|
const type = el.type ? `type="${el.type}"` : "";
|
||||||
} = attrBuilder(el)
|
const icon = el.icon ? `icon="${el.icon}"` : "";
|
||||||
const type = el.type ? `type="${el.type}"` : ''
|
const round = el.round ? "round" : "";
|
||||||
const icon = el.icon ? `icon="${el.icon}"` : ''
|
const size = el.size ? `size="${el.size}"` : "";
|
||||||
const round = el.round ? 'round' : ''
|
const plain = el.plain ? "plain" : "";
|
||||||
const size = el.size ? `size="${el.size}"` : ''
|
const circle = el.circle ? "circle" : "";
|
||||||
const plain = el.plain ? 'plain' : ''
|
let child = buildElButtonChild(el);
|
||||||
const circle = el.circle ? 'circle' : ''
|
|
||||||
let child = buildElButtonChild(el)
|
|
||||||
|
|
||||||
if (child) child = `\n${child}\n` // 换行
|
if (child) child = `\n${child}\n`; // 换行
|
||||||
return `<${tag} ${type} ${icon} ${round} ${size} ${plain} ${disabled} ${circle}>${child}</${tag}>`
|
return `<${tag} ${type} ${icon} ${round} ${size} ${plain} ${disabled} ${circle}>${child}</${tag}>`;
|
||||||
},
|
},
|
||||||
'el-input': el => {
|
"el-input": (el) => {
|
||||||
const {
|
const { tag, disabled, vModel, clearable, placeholder, width } =
|
||||||
tag, disabled, vModel, clearable, placeholder, width
|
attrBuilder(el);
|
||||||
} = attrBuilder(el)
|
const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : "";
|
||||||
const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : ''
|
const showWordLimit = el["show-word-limit"] ? "show-word-limit" : "";
|
||||||
const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : ''
|
const readonly = el.readonly ? "readonly" : "";
|
||||||
const readonly = el.readonly ? 'readonly' : ''
|
const prefixIcon = el["prefix-icon"]
|
||||||
const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : ''
|
? `prefix-icon='${el["prefix-icon"]}'`
|
||||||
const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : ''
|
: "";
|
||||||
const showPassword = el['show-password'] ? 'show-password' : ''
|
const suffixIcon = el["suffix-icon"]
|
||||||
const type = el.type ? `type="${el.type}"` : ''
|
? `suffix-icon='${el["suffix-icon"]}'`
|
||||||
const autosize = el.autosize && el.autosize.minRows
|
: "";
|
||||||
? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
|
const showPassword = el["show-password"] ? "show-password" : "";
|
||||||
: ''
|
const type = el.type ? `type="${el.type}"` : "";
|
||||||
let child = buildElInputChild(el)
|
const autosize =
|
||||||
|
el.autosize && el.autosize.minRows
|
||||||
|
? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
|
||||||
|
: "";
|
||||||
|
let child = buildElInputChild(el);
|
||||||
|
|
||||||
if (child) child = `\n${child}\n` // 换行
|
if (child) child = `\n${child}\n`; // 换行
|
||||||
return `<${tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${tag}>`
|
return `<${tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${tag}>`;
|
||||||
},
|
},
|
||||||
'el-input-number': el => {
|
"el-input-number": (el) => {
|
||||||
const {
|
const { tag, disabled, vModel, placeholder } = attrBuilder(el);
|
||||||
tag, disabled, vModel, placeholder
|
const controlsPosition = el["controls-position"]
|
||||||
} = attrBuilder(el)
|
? `controls-position=${el["controls-position"]}`
|
||||||
const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : ''
|
: "";
|
||||||
const min = el.min ? `:min='${el.min}'` : ''
|
const min = el.min ? `:min='${el.min}'` : "";
|
||||||
const max = el.max ? `:max='${el.max}'` : ''
|
const max = el.max ? `:max='${el.max}'` : "";
|
||||||
const step = el.step ? `:step='${el.step}'` : ''
|
const step = el.step ? `:step='${el.step}'` : "";
|
||||||
const stepStrictly = el['step-strictly'] ? 'step-strictly' : ''
|
const stepStrictly = el["step-strictly"] ? "step-strictly" : "";
|
||||||
const precision = el.precision ? `:precision='${el.precision}'` : ''
|
const precision = el.precision ? `:precision='${el.precision}'` : "";
|
||||||
|
|
||||||
return `<${tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${tag}>`
|
return `<${tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-select': el => {
|
"el-select": (el) => {
|
||||||
const {
|
const { tag, disabled, vModel, clearable, placeholder, width } =
|
||||||
tag, disabled, vModel, clearable, placeholder, width
|
attrBuilder(el);
|
||||||
} = attrBuilder(el)
|
const filterable = el.filterable ? "filterable" : "";
|
||||||
const filterable = el.filterable ? 'filterable' : ''
|
const multiple = el.multiple ? "multiple" : "";
|
||||||
const multiple = el.multiple ? 'multiple' : ''
|
let child = buildElSelectChild(el);
|
||||||
let child = buildElSelectChild(el)
|
|
||||||
|
|
||||||
if (child) child = `\n${child}\n` // 换行
|
if (child) child = `\n${child}\n`; // 换行
|
||||||
return `<${tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${tag}>`
|
return `<${tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${tag}>`;
|
||||||
},
|
},
|
||||||
'el-radio-group': el => {
|
"el-radio-group": (el) => {
|
||||||
const { tag, disabled, vModel } = attrBuilder(el)
|
const { tag, disabled, vModel } = attrBuilder(el);
|
||||||
const size = `size="${el.size}"`
|
const size = `size="${el.size}"`;
|
||||||
let child = buildElRadioGroupChild(el)
|
let child = buildElRadioGroupChild(el);
|
||||||
|
|
||||||
if (child) child = `\n${child}\n` // 换行
|
if (child) child = `\n${child}\n`; // 换行
|
||||||
return `<${tag} ${vModel} ${size} ${disabled}>${child}</${tag}>`
|
return `<${tag} ${vModel} ${size} ${disabled}>${child}</${tag}>`;
|
||||||
},
|
},
|
||||||
'el-checkbox-group': el => {
|
"el-checkbox-group": (el) => {
|
||||||
const { tag, disabled, vModel } = attrBuilder(el)
|
const { tag, disabled, vModel } = attrBuilder(el);
|
||||||
const size = `size="${el.size}"`
|
const size = `size="${el.size}"`;
|
||||||
const min = el.min ? `:min="${el.min}"` : ''
|
const min = el.min ? `:min="${el.min}"` : "";
|
||||||
const max = el.max ? `:max="${el.max}"` : ''
|
const max = el.max ? `:max="${el.max}"` : "";
|
||||||
let child = buildElCheckboxGroupChild(el)
|
let child = buildElCheckboxGroupChild(el);
|
||||||
|
|
||||||
if (child) child = `\n${child}\n` // 换行
|
if (child) child = `\n${child}\n`; // 换行
|
||||||
return `<${tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${tag}>`
|
return `<${tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${tag}>`;
|
||||||
},
|
},
|
||||||
'el-switch': el => {
|
"el-switch": (el) => {
|
||||||
const { tag, disabled, vModel } = attrBuilder(el)
|
const { tag, disabled, vModel } = attrBuilder(el);
|
||||||
const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : ''
|
const activeText = el["active-text"]
|
||||||
const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : ''
|
? `active-text="${el["active-text"]}"`
|
||||||
const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : ''
|
: "";
|
||||||
const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : ''
|
const inactiveText = el["inactive-text"]
|
||||||
const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : ''
|
? `inactive-text="${el["inactive-text"]}"`
|
||||||
const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : ''
|
: "";
|
||||||
|
const activeColor = el["active-color"]
|
||||||
|
? `active-color="${el["active-color"]}"`
|
||||||
|
: "";
|
||||||
|
const inactiveColor = el["inactive-color"]
|
||||||
|
? `inactive-color="${el["inactive-color"]}"`
|
||||||
|
: "";
|
||||||
|
const activeValue =
|
||||||
|
el["active-value"] !== true
|
||||||
|
? `:active-value='${JSON.stringify(el["active-value"])}'`
|
||||||
|
: "";
|
||||||
|
const inactiveValue =
|
||||||
|
el["inactive-value"] !== false
|
||||||
|
? `:inactive-value='${JSON.stringify(el["inactive-value"])}'`
|
||||||
|
: "";
|
||||||
|
|
||||||
return `<${tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${tag}>`
|
return `<${tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-cascader': el => {
|
"el-cascader": (el) => {
|
||||||
const {
|
const { tag, disabled, vModel, clearable, placeholder, width } =
|
||||||
tag, disabled, vModel, clearable, placeholder, width
|
attrBuilder(el);
|
||||||
} = attrBuilder(el)
|
const options = el.options ? `:options="${el.__vModel__}Options"` : "";
|
||||||
const options = el.options ? `:options="${el.__vModel__}Options"` : ''
|
const props = el.props ? `:props="${el.__vModel__}Props"` : "";
|
||||||
const props = el.props ? `:props="${el.__vModel__}Props"` : ''
|
const showAllLevels = el["show-all-levels"]
|
||||||
const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"'
|
? ""
|
||||||
const filterable = el.filterable ? 'filterable' : ''
|
: ':show-all-levels="false"';
|
||||||
const separator = el.separator === '/' ? '' : `separator="${el.separator}"`
|
const filterable = el.filterable ? "filterable" : "";
|
||||||
|
const separator = el.separator === "/" ? "" : `separator="${el.separator}"`;
|
||||||
|
|
||||||
return `<${tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${tag}>`
|
return `<${tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-slider': el => {
|
"el-slider": (el) => {
|
||||||
const { tag, disabled, vModel } = attrBuilder(el)
|
const { tag, disabled, vModel } = attrBuilder(el);
|
||||||
const min = el.min ? `:min='${el.min}'` : ''
|
const min = el.min ? `:min='${el.min}'` : "";
|
||||||
const max = el.max ? `:max='${el.max}'` : ''
|
const max = el.max ? `:max='${el.max}'` : "";
|
||||||
const step = el.step ? `:step='${el.step}'` : ''
|
const step = el.step ? `:step='${el.step}'` : "";
|
||||||
const range = el.range ? 'range' : ''
|
const range = el.range ? "range" : "";
|
||||||
const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : ''
|
const showStops = el["show-stops"]
|
||||||
|
? `:show-stops="${el["show-stops"]}"`
|
||||||
|
: "";
|
||||||
|
|
||||||
return `<${tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${tag}>`
|
return `<${tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-time-picker': el => {
|
"el-time-picker": (el) => {
|
||||||
const {
|
const { tag, disabled, vModel, clearable, placeholder, width } =
|
||||||
tag, disabled, vModel, clearable, placeholder, width
|
attrBuilder(el);
|
||||||
} = attrBuilder(el)
|
const startPlaceholder = el["start-placeholder"]
|
||||||
const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
|
? `start-placeholder="${el["start-placeholder"]}"`
|
||||||
const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
|
: "";
|
||||||
const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
|
const endPlaceholder = el["end-placeholder"]
|
||||||
const isRange = el['is-range'] ? 'is-range' : ''
|
? `end-placeholder="${el["end-placeholder"]}"`
|
||||||
const format = el.format ? `format="${el.format}"` : ''
|
: "";
|
||||||
const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
|
const rangeSeparator = el["range-separator"]
|
||||||
const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : ''
|
? `range-separator="${el["range-separator"]}"`
|
||||||
|
: "";
|
||||||
|
const isRange = el["is-range"] ? "is-range" : "";
|
||||||
|
const format = el.format ? `format="${el.format}"` : "";
|
||||||
|
const valueFormat = el["value-format"]
|
||||||
|
? `value-format="${el["value-format"]}"`
|
||||||
|
: "";
|
||||||
|
const pickerOptions = el["picker-options"]
|
||||||
|
? `:picker-options='${JSON.stringify(el["picker-options"])}'`
|
||||||
|
: "";
|
||||||
|
|
||||||
return `<${tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${tag}>`
|
return `<${tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-date-picker': el => {
|
"el-date-picker": (el) => {
|
||||||
const {
|
const { tag, disabled, vModel, clearable, placeholder, width } =
|
||||||
tag, disabled, vModel, clearable, placeholder, width
|
attrBuilder(el);
|
||||||
} = attrBuilder(el)
|
const startPlaceholder = el["start-placeholder"]
|
||||||
const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
|
? `start-placeholder="${el["start-placeholder"]}"`
|
||||||
const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
|
: "";
|
||||||
const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
|
const endPlaceholder = el["end-placeholder"]
|
||||||
const format = el.format ? `format="${el.format}"` : ''
|
? `end-placeholder="${el["end-placeholder"]}"`
|
||||||
const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
|
: "";
|
||||||
const type = el.type === 'date' ? '' : `type="${el.type}"`
|
const rangeSeparator = el["range-separator"]
|
||||||
const readonly = el.readonly ? 'readonly' : ''
|
? `range-separator="${el["range-separator"]}"`
|
||||||
|
: "";
|
||||||
|
const format = el.format ? `format="${el.format}"` : "";
|
||||||
|
const valueFormat = el["value-format"]
|
||||||
|
? `value-format="${el["value-format"]}"`
|
||||||
|
: "";
|
||||||
|
const type = el.type === "date" ? "" : `type="${el.type}"`;
|
||||||
|
const readonly = el.readonly ? "readonly" : "";
|
||||||
|
|
||||||
return `<${tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${tag}>`
|
return `<${tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-rate': el => {
|
"el-rate": (el) => {
|
||||||
const { tag, disabled, vModel } = attrBuilder(el)
|
const { tag, disabled, vModel } = attrBuilder(el);
|
||||||
const max = el.max ? `:max='${el.max}'` : ''
|
const max = el.max ? `:max='${el.max}'` : "";
|
||||||
const allowHalf = el['allow-half'] ? 'allow-half' : ''
|
const allowHalf = el["allow-half"] ? "allow-half" : "";
|
||||||
const showText = el['show-text'] ? 'show-text' : ''
|
const showText = el["show-text"] ? "show-text" : "";
|
||||||
const showScore = el['show-score'] ? 'show-score' : ''
|
const showScore = el["show-score"] ? "show-score" : "";
|
||||||
|
|
||||||
return `<${tag} ${vModel} ${max} ${allowHalf} ${showText} ${showScore} ${disabled}></${tag}>`
|
return `<${tag} ${vModel} ${max} ${allowHalf} ${showText} ${showScore} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-color-picker': el => {
|
"el-color-picker": (el) => {
|
||||||
const { tag, disabled, vModel } = attrBuilder(el)
|
const { tag, disabled, vModel } = attrBuilder(el);
|
||||||
const size = `size="${el.size}"`
|
const size = `size="${el.size}"`;
|
||||||
const showAlpha = el['show-alpha'] ? 'show-alpha' : ''
|
const showAlpha = el["show-alpha"] ? "show-alpha" : "";
|
||||||
const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : ''
|
const colorFormat = el["color-format"]
|
||||||
|
? `color-format="${el["color-format"]}"`
|
||||||
|
: "";
|
||||||
|
|
||||||
return `<${tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${tag}>`
|
return `<${tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${tag}>`;
|
||||||
},
|
},
|
||||||
'el-upload': el => {
|
"el-upload": (el) => {
|
||||||
const { tag } = el.__config__
|
const { tag } = el.__config__;
|
||||||
const disabled = el.disabled ? ':disabled=\'true\'' : ''
|
const disabled = el.disabled ? ":disabled='true'" : "";
|
||||||
const action = el.action ? `:action="${el.__vModel__}Action"` : ''
|
const action = el.action ? `:action="${el.__vModel__}Action"` : "";
|
||||||
const multiple = el.multiple ? 'multiple' : ''
|
const multiple = el.multiple ? "multiple" : "";
|
||||||
const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : ''
|
const listType =
|
||||||
const accept = el.accept ? `accept="${el.accept}"` : ''
|
el["list-type"] !== "text" ? `list-type="${el["list-type"]}"` : "";
|
||||||
const name = el.name !== 'file' ? `name="${el.name}"` : ''
|
const accept = el.accept ? `accept="${el.accept}"` : "";
|
||||||
const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : ''
|
const name = el.name !== "file" ? `name="${el.name}"` : "";
|
||||||
const beforeUpload = `:before-upload="${el.__vModel__}BeforeUpload"`
|
const autoUpload =
|
||||||
const fileList = `:file-list="${el.__vModel__}fileList"`
|
el["auto-upload"] === false ? ':auto-upload="false"' : "";
|
||||||
const ref = `ref="${el.__vModel__}"`
|
const beforeUpload = `:before-upload="${el.__vModel__}BeforeUpload"`;
|
||||||
let child = buildElUploadChild(el)
|
const fileList = `:file-list="${el.__vModel__}fileList"`;
|
||||||
|
const ref = `ref="${el.__vModel__}"`;
|
||||||
|
let child = buildElUploadChild(el);
|
||||||
|
|
||||||
if (child) child = `\n${child}\n` // 换行
|
if (child) child = `\n${child}\n`; // 换行
|
||||||
return `<${tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${tag}>`
|
return `<${tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${tag}>`;
|
||||||
},
|
},
|
||||||
tinymce: el => {
|
tinymce: (el) => {
|
||||||
const { tag, vModel, placeholder } = attrBuilder(el)
|
const { tag, vModel, placeholder } = attrBuilder(el);
|
||||||
const height = el.height ? `:height="${el.height}"` : ''
|
const height = el.height ? `:height="${el.height}"` : "";
|
||||||
const branding = el.branding ? `:branding="${el.branding}"` : ''
|
const branding = el.branding ? `:branding="${el.branding}"` : "";
|
||||||
return `<${tag} ${vModel} ${placeholder} ${height} ${branding}></${tag}>`
|
return `<${tag} ${vModel} ${placeholder} ${height} ${branding}></${tag}>`;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
function attrBuilder(el) {
|
function attrBuilder(el) {
|
||||||
return {
|
return {
|
||||||
tag: el.__config__.tag,
|
tag: el.__config__.tag,
|
||||||
vModel: `v-model="${confGlobal.formModel}.${el.__vModel__}"`,
|
vModel: `v-model="${confGlobal.formModel}.${el.__vModel__}"`,
|
||||||
clearable: el.clearable ? 'clearable' : '',
|
clearable: el.clearable ? "clearable" : "",
|
||||||
placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '',
|
placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : "",
|
||||||
width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '',
|
width: el.style && el.style.width ? ":style=\"{width: '100%'}\"" : "",
|
||||||
disabled: el.disabled ? ':disabled=\'true\'' : ''
|
disabled: el.disabled ? ":disabled='true'" : "",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-buttin 子级
|
// el-buttin 子级
|
||||||
function buildElButtonChild(scheme) {
|
function buildElButtonChild(scheme) {
|
||||||
const children = []
|
const children = [];
|
||||||
const slot = scheme.__slot__ || {}
|
const slot = scheme.__slot__ || {};
|
||||||
if (slot.default) {
|
if (slot.default) {
|
||||||
children.push(slot.default)
|
children.push(slot.default);
|
||||||
}
|
}
|
||||||
return children.join('\n')
|
return children.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-input 子级
|
// el-input 子级
|
||||||
function buildElInputChild(scheme) {
|
function buildElInputChild(scheme) {
|
||||||
const children = []
|
const children = [];
|
||||||
const slot = scheme.__slot__
|
const slot = scheme.__slot__;
|
||||||
if (slot && slot.prepend) {
|
if (slot && slot.prepend) {
|
||||||
children.push(`<template slot="prepend">${slot.prepend}</template>`)
|
children.push(`<template slot="prepend">${slot.prepend}</template>`);
|
||||||
}
|
}
|
||||||
if (slot && slot.append) {
|
if (slot && slot.append) {
|
||||||
children.push(`<template slot="append">${slot.append}</template>`)
|
children.push(`<template slot="append">${slot.append}</template>`);
|
||||||
}
|
}
|
||||||
return children.join('\n')
|
return children.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-select 子级
|
// el-select 子级
|
||||||
function buildElSelectChild(scheme) {
|
function buildElSelectChild(scheme) {
|
||||||
const children = []
|
const children = [];
|
||||||
const slot = scheme.__slot__
|
const slot = scheme.__slot__;
|
||||||
if (slot && slot.options && slot.options.length) {
|
if (slot && slot.options && slot.options.length) {
|
||||||
children.push(`<el-option v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`)
|
children.push(
|
||||||
|
`<el-option v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return children.join('\n')
|
return children.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-radio-group 子级
|
// el-radio-group 子级
|
||||||
function buildElRadioGroupChild(scheme) {
|
function buildElRadioGroupChild(scheme) {
|
||||||
const children = []
|
const children = [];
|
||||||
const slot = scheme.__slot__
|
const slot = scheme.__slot__;
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
if (slot && slot.options && slot.options.length) {
|
if (slot && slot.options && slot.options.length) {
|
||||||
const tag = config.optionType === 'button' ? 'el-radio-button' : 'el-radio'
|
const tag = config.optionType === "button" ? "el-radio-button" : "el-radio";
|
||||||
const border = config.border ? 'border' : ''
|
const border = config.border ? "border" : "";
|
||||||
children.push(`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
|
children.push(
|
||||||
|
`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return children.join('\n')
|
return children.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-checkbox-group 子级
|
// el-checkbox-group 子级
|
||||||
function buildElCheckboxGroupChild(scheme) {
|
function buildElCheckboxGroupChild(scheme) {
|
||||||
const children = []
|
const children = [];
|
||||||
const slot = scheme.__slot__
|
const slot = scheme.__slot__;
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
if (slot && slot.options && slot.options.length) {
|
if (slot && slot.options && slot.options.length) {
|
||||||
const tag = config.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox'
|
const tag =
|
||||||
const border = config.border ? 'border' : ''
|
config.optionType === "button" ? "el-checkbox-button" : "el-checkbox";
|
||||||
children.push(`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`)
|
const border = config.border ? "border" : "";
|
||||||
|
children.push(
|
||||||
|
`<${tag} v-for="(item, index) in ${scheme.__vModel__}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return children.join('\n')
|
return children.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-upload 子级
|
// el-upload 子级
|
||||||
function buildElUploadChild(scheme) {
|
function buildElUploadChild(scheme) {
|
||||||
const list = []
|
const list = [];
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
if (scheme['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>')
|
if (scheme["list-type"] === "picture-card")
|
||||||
else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${config.buttonText}</el-button>`)
|
list.push('<i class="el-icon-plus"></i>');
|
||||||
if (config.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${config.fileSize}${config.sizeUnit} 的${scheme.accept}文件</div>`)
|
else
|
||||||
return list.join('\n')
|
list.push(
|
||||||
|
`<el-button size="small" type="primary" icon="el-icon-upload">${config.buttonText}</el-button>`
|
||||||
|
);
|
||||||
|
if (config.showTip)
|
||||||
|
list.push(
|
||||||
|
`<div slot="tip" class="el-upload__tip">只能上传不超过 ${config.fileSize}${config.sizeUnit} 的${scheme.accept}文件</div>`
|
||||||
|
);
|
||||||
|
return list.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -379,21 +439,23 @@ function buildElUploadChild(scheme) {
|
|||||||
* @param {String} type 生成类型,文件或弹窗等
|
* @param {String} type 生成类型,文件或弹窗等
|
||||||
*/
|
*/
|
||||||
export function makeUpHtml(formConfig, type) {
|
export function makeUpHtml(formConfig, type) {
|
||||||
const htmlList = []
|
const htmlList = [];
|
||||||
confGlobal = formConfig
|
confGlobal = formConfig;
|
||||||
// 判断布局是否都沾满了24个栅格,以备后续简化代码结构
|
// 判断布局是否都沾满了24个栅格,以备后续简化代码结构
|
||||||
someSpanIsNot24 = formConfig.fields.some(item => item.__config__.span !== 24)
|
someSpanIsNot24 = formConfig.fields.some(
|
||||||
|
(item) => item.__config__.span !== 24
|
||||||
|
);
|
||||||
// 遍历渲染每个组件成html
|
// 遍历渲染每个组件成html
|
||||||
formConfig.fields.forEach(el => {
|
formConfig.fields.forEach((el) => {
|
||||||
htmlList.push(layouts[el.__config__.layout](el))
|
htmlList.push(layouts[el.__config__.layout](el));
|
||||||
})
|
});
|
||||||
const htmlStr = htmlList.join('\n')
|
const htmlStr = htmlList.join("\n");
|
||||||
// 将组件代码放进form标签
|
// 将组件代码放进form标签
|
||||||
let temp = buildFormTemplate(formConfig, htmlStr, type)
|
let temp = buildFormTemplate(formConfig, htmlStr, type);
|
||||||
// dialog标签包裹代码
|
// dialog标签包裹代码
|
||||||
if (type === 'dialog') {
|
if (type === "dialog") {
|
||||||
temp = dialogWrapper(temp)
|
temp = dialogWrapper(temp);
|
||||||
}
|
}
|
||||||
confGlobal = null
|
confGlobal = null;
|
||||||
return temp
|
return temp;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import { isArray } from 'util'
|
// import { Array.isArray } from 'util'
|
||||||
import { exportDefault, titleCase, deepClone } from '@/utils/index'
|
import { exportDefault, titleCase, deepClone } from "@/utils/index";
|
||||||
import ruleTrigger from './ruleTrigger'
|
import ruleTrigger from "./ruleTrigger";
|
||||||
|
|
||||||
const units = {
|
const units = {
|
||||||
KB: '1024',
|
KB: "1024",
|
||||||
MB: '1024 / 1024',
|
MB: "1024 / 1024",
|
||||||
GB: '1024 / 1024 / 1024'
|
GB: "1024 / 1024 / 1024",
|
||||||
}
|
};
|
||||||
let confGlobal
|
let confGlobal;
|
||||||
const inheritAttrs = {
|
const inheritAttrs = {
|
||||||
file: '',
|
file: "",
|
||||||
dialog: 'inheritAttrs: false,'
|
dialog: "inheritAttrs: false,",
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组装js 【入口函数】
|
* 组装js 【入口函数】
|
||||||
@ -19,212 +19,263 @@ const inheritAttrs = {
|
|||||||
* @param {String} type 生成类型,文件或弹窗等
|
* @param {String} type 生成类型,文件或弹窗等
|
||||||
*/
|
*/
|
||||||
export function makeUpJs(formConfig, type) {
|
export function makeUpJs(formConfig, type) {
|
||||||
confGlobal = formConfig = deepClone(formConfig)
|
confGlobal = formConfig = deepClone(formConfig);
|
||||||
const dataList = []
|
const dataList = [];
|
||||||
const ruleList = []
|
const ruleList = [];
|
||||||
const optionsList = []
|
const optionsList = [];
|
||||||
const propsList = []
|
const propsList = [];
|
||||||
const methodList = mixinMethod(type)
|
const methodList = mixinMethod(type);
|
||||||
const uploadVarList = []
|
const uploadVarList = [];
|
||||||
const created = []
|
const created = [];
|
||||||
|
|
||||||
formConfig.fields.forEach(el => {
|
|
||||||
buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
formConfig.fields.forEach((el) => {
|
||||||
|
buildAttributes(
|
||||||
|
el,
|
||||||
|
dataList,
|
||||||
|
ruleList,
|
||||||
|
optionsList,
|
||||||
|
methodList,
|
||||||
|
propsList,
|
||||||
|
uploadVarList,
|
||||||
|
created
|
||||||
|
);
|
||||||
|
});
|
||||||
|
console.log(
|
||||||
|
dataList,
|
||||||
|
ruleList,
|
||||||
|
optionsList,
|
||||||
|
methodList,
|
||||||
|
propsList,
|
||||||
|
uploadVarList,
|
||||||
|
created
|
||||||
|
);
|
||||||
const script = buildexport(
|
const script = buildexport(
|
||||||
formConfig,
|
formConfig,
|
||||||
type,
|
type,
|
||||||
dataList.join('\n'),
|
dataList.join("\n"),
|
||||||
ruleList.join('\n'),
|
ruleList.join("\n"),
|
||||||
optionsList.join('\n'),
|
optionsList.join("\n"),
|
||||||
uploadVarList.join('\n'),
|
uploadVarList.join("\n"),
|
||||||
propsList.join('\n'),
|
propsList.join("\n"),
|
||||||
methodList.join('\n'),
|
methodList.join("\n"),
|
||||||
created.join('\n')
|
created.join("\n")
|
||||||
)
|
);
|
||||||
confGlobal = null
|
confGlobal = null;
|
||||||
return script
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建组件属性
|
// 构建组件属性
|
||||||
function buildAttributes(scheme, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created) {
|
function buildAttributes(
|
||||||
const config = scheme.__config__
|
scheme,
|
||||||
const slot = scheme.__slot__
|
dataList,
|
||||||
buildData(scheme, dataList)
|
ruleList,
|
||||||
buildRules(scheme, ruleList)
|
optionsList,
|
||||||
|
methodList,
|
||||||
|
propsList,
|
||||||
|
uploadVarList,
|
||||||
|
created
|
||||||
|
) {
|
||||||
|
const config = scheme.__config__;
|
||||||
|
const slot = scheme.__slot__;
|
||||||
|
buildData(scheme, dataList);
|
||||||
|
buildRules(scheme, ruleList);
|
||||||
|
|
||||||
// 特殊处理options属性
|
// 特殊处理options属性
|
||||||
if (scheme.options || (slot && slot.options && slot.options.length)) {
|
if (scheme.options || (slot && slot.options && slot.options.length)) {
|
||||||
buildOptions(scheme, optionsList)
|
buildOptions(scheme, optionsList);
|
||||||
if (config.dataType === 'dynamic') {
|
if (config.dataType === "dynamic") {
|
||||||
const model = `${scheme.__vModel__}Options`
|
const model = `${scheme.__vModel__}Options`;
|
||||||
const options = titleCase(model)
|
const options = titleCase(model);
|
||||||
const methodName = `get${options}`
|
const methodName = `get${options}`;
|
||||||
buildOptionMethod(methodName, model, methodList, scheme)
|
buildOptionMethod(methodName, model, methodList, scheme);
|
||||||
callInCreated(methodName, created)
|
callInCreated(methodName, created);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理props
|
// 处理props
|
||||||
if (scheme.props && scheme.props.props) {
|
if (scheme.props && scheme.props.props) {
|
||||||
buildProps(scheme, propsList)
|
buildProps(scheme, propsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理el-upload的action
|
// 处理el-upload的action
|
||||||
if (scheme.action && config.tag === 'el-upload') {
|
if (scheme.action && config.tag === "el-upload") {
|
||||||
uploadVarList.push(
|
uploadVarList.push(
|
||||||
`${scheme.__vModel__}Action: '${scheme.action}',
|
`${scheme.__vModel__}Action: '${scheme.action}',
|
||||||
${scheme.__vModel__}fileList: [],`
|
${scheme.__vModel__}fileList: [],`
|
||||||
)
|
);
|
||||||
methodList.push(buildBeforeUpload(scheme))
|
methodList.push(buildBeforeUpload(scheme));
|
||||||
// 非自动上传时,生成手动上传的函数
|
// 非自动上传时,生成手动上传的函数
|
||||||
if (!scheme['auto-upload']) {
|
if (!scheme["auto-upload"]) {
|
||||||
methodList.push(buildSubmitUpload(scheme))
|
methodList.push(buildSubmitUpload(scheme));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建子级组件属性
|
// 构建子级组件属性
|
||||||
if (config.children) {
|
if (config.children) {
|
||||||
config.children.forEach(item => {
|
config.children.forEach((item) => {
|
||||||
buildAttributes(item, dataList, ruleList, optionsList, methodList, propsList, uploadVarList, created)
|
buildAttributes(
|
||||||
})
|
item,
|
||||||
|
dataList,
|
||||||
|
ruleList,
|
||||||
|
optionsList,
|
||||||
|
methodList,
|
||||||
|
propsList,
|
||||||
|
uploadVarList,
|
||||||
|
created
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在Created调用函数
|
// 在Created调用函数
|
||||||
function callInCreated(methodName, created) {
|
function callInCreated(methodName, created) {
|
||||||
created.push(`this.${methodName}()`)
|
created.push(`this.${methodName}()`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 混入处理函数
|
// 混入处理函数
|
||||||
function mixinMethod(type) {
|
function mixinMethod(type) {
|
||||||
const list = []; const
|
const list = [];
|
||||||
minxins = {
|
const minxins = {
|
||||||
file: confGlobal.formBtns ? {
|
file: confGlobal.formBtns
|
||||||
submitForm: `submitForm() {
|
? {
|
||||||
this.$refs['${confGlobal.formRef}'].validate(valid => {
|
submitForm: `const submitForm = () => {
|
||||||
|
${confGlobal.formRef}.value.validate(valid => {
|
||||||
if(!valid) return
|
if(!valid) return
|
||||||
// TODO 提交表单
|
// TODO 提交表单
|
||||||
})
|
})
|
||||||
|
}`,
|
||||||
|
resetForm: `const resetForm = () => {
|
||||||
|
${confGlobal.formRef}.value.resetFields()
|
||||||
|
}`,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
dialog: {
|
||||||
|
onOpen: "const onOpen = () => {},",
|
||||||
|
onClose: `const onClose = () => {
|
||||||
|
${confGlobal.formRef}.value.resetFields()
|
||||||
},`,
|
},`,
|
||||||
resetForm: `resetForm() {
|
close: `const close = () => {
|
||||||
this.$refs['${confGlobal.formRef}'].resetFields()
|
|
||||||
},`
|
|
||||||
} : null,
|
|
||||||
dialog: {
|
|
||||||
onOpen: 'onOpen() {},',
|
|
||||||
onClose: `onClose() {
|
|
||||||
this.$refs['${confGlobal.formRef}'].resetFields()
|
|
||||||
},`,
|
|
||||||
close: `close() {
|
|
||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false)
|
||||||
},`,
|
},`,
|
||||||
handelConfirm: `handelConfirm() {
|
handelConfirm: `const handelConfirm = () => {
|
||||||
this.$refs['${confGlobal.formRef}'].validate(valid => {
|
${confGlobal.formRef}.value.validate(valid => {
|
||||||
if(!valid) return
|
if(!valid) return
|
||||||
this.close()
|
this.close()
|
||||||
})
|
})
|
||||||
},`
|
},`,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const methods = minxins[type]
|
const methods = minxins[type];
|
||||||
if (methods) {
|
if (methods) {
|
||||||
Object.keys(methods).forEach(key => {
|
Object.keys(methods).forEach((key) => {
|
||||||
list.push(methods[key])
|
list.push(methods[key]);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return list
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建data
|
// 构建data
|
||||||
function buildData(scheme, dataList) {
|
function buildData(scheme, dataList) {
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
if (scheme.__vModel__ === undefined) return
|
if (scheme.__vModel__ === undefined) return;
|
||||||
const defaultValue = JSON.stringify(config.defaultValue)
|
const defaultValue = JSON.stringify(config.defaultValue);
|
||||||
dataList.push(`${scheme.__vModel__}: ${defaultValue},`)
|
dataList.push(`${scheme.__vModel__}: ${defaultValue},`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建校验规则
|
// 构建校验规则
|
||||||
function buildRules(scheme, ruleList) {
|
function buildRules(scheme, ruleList) {
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
if (scheme.__vModel__ === undefined) return
|
if (scheme.__vModel__ === undefined) return;
|
||||||
const rules = []
|
const rules = [];
|
||||||
if (ruleTrigger[config.tag]) {
|
if (ruleTrigger[config.tag]) {
|
||||||
if (config.required) {
|
if (config.required) {
|
||||||
const type = isArray(config.defaultValue) ? 'type: \'array\',' : ''
|
const type = Array.isArray(config.defaultValue) ? "type: 'array'," : "";
|
||||||
let message = isArray(config.defaultValue) ? `请至少选择一个${config.label}` : scheme.placeholder
|
let message = Array.isArray(config.defaultValue)
|
||||||
if (message === undefined) message = `${config.label}不能为空`
|
? `请至少选择一个${config.label}`
|
||||||
rules.push(`{ required: true, ${type} message: '${message}', trigger: '${ruleTrigger[config.tag]}' }`)
|
: scheme.placeholder;
|
||||||
|
if (message === undefined) message = `${config.label}不能为空`;
|
||||||
|
rules.push(
|
||||||
|
`{ required: true, ${type} message: '${message}', trigger: '${
|
||||||
|
ruleTrigger[config.tag]
|
||||||
|
}' }`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (config.regList && isArray(config.regList)) {
|
if (config.regList && Array.isArray(config.regList)) {
|
||||||
config.regList.forEach(item => {
|
config.regList.forEach((item) => {
|
||||||
if (item.pattern) {
|
if (item.pattern) {
|
||||||
rules.push(
|
rules.push(
|
||||||
`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${ruleTrigger[config.tag]}' }`
|
`{ pattern: ${eval(item.pattern)}, message: '${
|
||||||
)
|
item.message
|
||||||
|
}', trigger: '${ruleTrigger[config.tag]}' }`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
ruleList.push(`${scheme.__vModel__}: [${rules.join(',')}],`)
|
ruleList.push(`${scheme.__vModel__}: [${rules.join(",")}],`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建options
|
// 构建options
|
||||||
function buildOptions(scheme, optionsList) {
|
function buildOptions(scheme, optionsList) {
|
||||||
if (scheme.__vModel__ === undefined) return
|
if (scheme.__vModel__ === undefined) return;
|
||||||
// el-cascader直接有options属性,其他组件都是定义在slot中,所以有两处判断
|
// el-cascader直接有options属性,其他组件都是定义在slot中,所以有两处判断
|
||||||
let { options } = scheme
|
let { options } = scheme;
|
||||||
if (!options) options = scheme.__slot__.options
|
if (!options) options = scheme.__slot__.options;
|
||||||
if (scheme.__config__.dataType === 'dynamic') { options = [] }
|
if (scheme.__config__.dataType === "dynamic") {
|
||||||
const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)},`
|
options = [];
|
||||||
optionsList.push(str)
|
}
|
||||||
|
const str = `${scheme.__vModel__}Options: ${JSON.stringify(options)},`;
|
||||||
|
optionsList.push(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildProps(scheme, propsList) {
|
function buildProps(scheme, propsList) {
|
||||||
const str = `${scheme.__vModel__}Props: ${JSON.stringify(scheme.props.props)},`
|
const str = `${scheme.__vModel__}Props: ${JSON.stringify(
|
||||||
propsList.push(str)
|
scheme.props.props
|
||||||
|
)},`;
|
||||||
|
propsList.push(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-upload的BeforeUpload
|
// el-upload的BeforeUpload
|
||||||
function buildBeforeUpload(scheme) {
|
function buildBeforeUpload(scheme) {
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
const unitNum = units[config.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
|
const unitNum = units[config.sizeUnit];
|
||||||
returnList = []
|
let rightSizeCode = "";
|
||||||
|
let acceptCode = "";
|
||||||
|
const returnList = [];
|
||||||
if (config.fileSize) {
|
if (config.fileSize) {
|
||||||
rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
|
rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${config.fileSize}
|
||||||
if(!isRightSize){
|
if(!isRightSize){
|
||||||
this.$message.error('文件大小超过 ${config.fileSize}${config.sizeUnit}')
|
this.$message.error('文件大小超过 ${config.fileSize}${config.sizeUnit}')
|
||||||
}`
|
}`;
|
||||||
returnList.push('isRightSize')
|
returnList.push("isRightSize");
|
||||||
}
|
}
|
||||||
if (scheme.accept) {
|
if (scheme.accept) {
|
||||||
acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
|
acceptCode = `let isAccept = new RegExp('${scheme.accept}').test(file.type)
|
||||||
if(!isAccept){
|
if(!isAccept){
|
||||||
this.$message.error('应该选择${scheme.accept}类型的文件')
|
this.$message.error('应该选择${scheme.accept}类型的文件')
|
||||||
}`
|
}`;
|
||||||
returnList.push('isAccept')
|
returnList.push("isAccept");
|
||||||
}
|
}
|
||||||
const str = `${scheme.__vModel__}BeforeUpload(file) {
|
const str = `${scheme.__vModel__}BeforeUpload(file) {
|
||||||
${rightSizeCode}
|
${rightSizeCode}
|
||||||
${acceptCode}
|
${acceptCode}
|
||||||
return ${returnList.join('&&')}
|
return ${returnList.join("&&")}
|
||||||
},`
|
},`;
|
||||||
return returnList.length ? str : ''
|
return returnList.length ? str : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// el-upload的submit
|
// el-upload的submit
|
||||||
function buildSubmitUpload(scheme) {
|
function buildSubmitUpload(scheme) {
|
||||||
const str = `submitUpload() {
|
const str = `submitUpload() {
|
||||||
this.$refs['${scheme.__vModel__}'].submit()
|
this.$refs['${scheme.__vModel__}'].submit()
|
||||||
},`
|
},`;
|
||||||
return str
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildOptionMethod(methodName, model, methodList, scheme) {
|
function buildOptionMethod(methodName, model, methodList, scheme) {
|
||||||
const config = scheme.__config__
|
const config = scheme.__config__;
|
||||||
const str = `${methodName}() {
|
const str = `${methodName}() {
|
||||||
// 注意:this.$axios是通过Vue.prototype.$axios = axios挂载产生的
|
// 注意:this.$axios是通过Vue.prototype.$axios = axios挂载产生的
|
||||||
this.$axios({
|
this.$axios({
|
||||||
@ -234,12 +285,42 @@ function buildOptionMethod(methodName, model, methodList, scheme) {
|
|||||||
var { data } = resp
|
var { data } = resp
|
||||||
this.${model} = data.${config.dataKey}
|
this.${model} = data.${config.dataKey}
|
||||||
})
|
})
|
||||||
},`
|
},`;
|
||||||
methodList.push(str)
|
methodList.push(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// js整体拼接
|
// js整体拼接
|
||||||
function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods, created) {
|
function buildexport(
|
||||||
|
conf,
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
rules,
|
||||||
|
selectOptions,
|
||||||
|
uploadVar,
|
||||||
|
props,
|
||||||
|
methods,
|
||||||
|
created
|
||||||
|
) {
|
||||||
|
const newStr = `
|
||||||
|
import { ref, reactive, toRefs } from "vue";
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
${conf.formModel}: {
|
||||||
|
${data}
|
||||||
|
},
|
||||||
|
${conf.formRules}: {
|
||||||
|
${rules}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { ${conf.formModel}, ${conf.formRules} } = toRefs(data);
|
||||||
|
const ${confGlobal.formRef} = ref();
|
||||||
|
${methods}
|
||||||
|
|
||||||
|
${created}
|
||||||
|
`;
|
||||||
|
return newStr;
|
||||||
|
|
||||||
const str = `${exportDefault}{
|
const str = `${exportDefault}{
|
||||||
${inheritAttrs[type]}
|
${inheritAttrs[type]}
|
||||||
components: {},
|
components: {},
|
||||||
@ -266,6 +347,6 @@ function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, m
|
|||||||
methods: {
|
methods: {
|
||||||
${methods}
|
${methods}
|
||||||
}
|
}
|
||||||
}`
|
}`;
|
||||||
return str
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,39 @@
|
|||||||
import { deepClone } from "@/utils/index";
|
import { deepClone } from "@/utils/index";
|
||||||
import {
|
import {
|
||||||
ElButton,
|
|
||||||
ElColorPicker,
|
|
||||||
ElDatePicker,
|
|
||||||
ElInput,
|
|
||||||
ElInputNumber,
|
|
||||||
ElRate,
|
|
||||||
ElRow,
|
ElRow,
|
||||||
ElSelect,
|
ElRate,
|
||||||
|
ElInput,
|
||||||
ElSlider,
|
ElSlider,
|
||||||
|
ElSelect,
|
||||||
|
ElButton,
|
||||||
ElSwitch,
|
ElSwitch,
|
||||||
ElTimePicker,
|
|
||||||
ElUpload,
|
ElUpload,
|
||||||
|
ElCascader,
|
||||||
|
ElDatePicker,
|
||||||
|
ElTimePicker,
|
||||||
|
ElRadioGroup,
|
||||||
|
ElColorPicker,
|
||||||
|
ElInputNumber,
|
||||||
|
ElCheckboxGroup,
|
||||||
} from "element-plus";
|
} from "element-plus";
|
||||||
import { h, defineComponent } from "vue";
|
import { h, defineComponent } from "vue";
|
||||||
// import "element-plus/es/components/input";
|
|
||||||
const formComponentsMap = {
|
const formComponentsMap = {
|
||||||
|
"el-row": ElRow,
|
||||||
|
"el-rate": ElRate,
|
||||||
"el-input": ElInput,
|
"el-input": ElInput,
|
||||||
"el-input-number": ElInputNumber,
|
|
||||||
"el-switch": ElSwitch,
|
"el-switch": ElSwitch,
|
||||||
"el-select": ElSelect,
|
"el-select": ElSelect,
|
||||||
"el-time-picker": ElTimePicker,
|
|
||||||
"el-color-picker": ElColorPicker,
|
|
||||||
"el-date-picker": ElDatePicker,
|
|
||||||
"el-button": ElButton,
|
|
||||||
"el-row": ElRow,
|
|
||||||
"el-slider": ElSlider,
|
|
||||||
"el-rate": ElRate,
|
|
||||||
"el-upload": ElUpload,
|
"el-upload": ElUpload,
|
||||||
|
"el-button": ElButton,
|
||||||
|
"el-slider": ElSlider,
|
||||||
|
"el-cascader": ElCascader,
|
||||||
|
"el-time-picker": ElTimePicker,
|
||||||
|
"el-radio-group": ElRadioGroup,
|
||||||
|
"el-date-picker": ElDatePicker,
|
||||||
|
"el-input-number": ElInputNumber,
|
||||||
|
"el-color-picker": ElColorPicker,
|
||||||
|
"el-checkbox-group": ElCheckboxGroup,
|
||||||
};
|
};
|
||||||
|
|
||||||
const componentChild = {};
|
const componentChild = {};
|
||||||
@ -46,11 +52,7 @@ keys.forEach((key) => {
|
|||||||
|
|
||||||
function vModel(dataObject, defaultValue) {
|
function vModel(dataObject, defaultValue) {
|
||||||
dataObject.props.value = defaultValue;
|
dataObject.props.value = defaultValue;
|
||||||
// dataObject.onInput = (val) => {
|
|
||||||
// this.$emit("input", val);
|
|
||||||
// };
|
|
||||||
dataObject.on.input = (val) => {
|
dataObject.on.input = (val) => {
|
||||||
console.log(val, "input");
|
|
||||||
this.$emit("input", val);
|
this.$emit("input", val);
|
||||||
};
|
};
|
||||||
dataObject.on.change = (val) => {
|
dataObject.on.change = (val) => {
|
||||||
@ -59,13 +61,13 @@ function vModel(dataObject, defaultValue) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mountSlotFiles(h, confClone, children) {
|
function mountSlotFiles(confClone, children) {
|
||||||
const childObjs = componentChild[confClone.__config__.tag];
|
const childObjs = componentChild[confClone.__config__.tag];
|
||||||
if (childObjs) {
|
if (childObjs) {
|
||||||
Object.keys(childObjs).forEach((key) => {
|
Object.keys(childObjs).forEach((key) => {
|
||||||
const childFunc = childObjs[key];
|
const childFunc = childObjs[key];
|
||||||
if (confClone.__slot__ && confClone.__slot__[key]) {
|
if (confClone.__slot__ && confClone.__slot__[key]) {
|
||||||
children.push(childFunc(h, confClone, key));
|
children.push(childFunc(confClone, key));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -172,105 +174,141 @@ export default defineComponent({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
arr: [],
|
||||||
|
tempTime: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
emits: ["input"],
|
emits: ["input"],
|
||||||
|
// setup(props, { slots, emit }) {
|
||||||
|
// const dataObject = makeDataObject();
|
||||||
|
// const confClone = deepClone(props.conf);
|
||||||
|
// // const children = [this.$slots.default] || [];
|
||||||
|
// console.log(slots, "slots");
|
||||||
|
// const children = [];
|
||||||
|
// // 如果slots文件夹存在与当前tag同名的文件,则执行文件中的代码
|
||||||
|
// mountSlotFiles(h, confClone, children);
|
||||||
|
|
||||||
|
// // 将字符串类型的事件,发送为消息
|
||||||
|
// emitEvents(emit, confClone);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// emit("input", "4ww3243");
|
||||||
|
// }, 3000);
|
||||||
|
// // 将json表单配置转化为vue render可以识别的 “数据对象(dataObject)”
|
||||||
|
// const update = (val) => {
|
||||||
|
// console.log(val, "update");
|
||||||
|
// emit("input", val);
|
||||||
|
// };
|
||||||
|
// buildDataObject(update, confClone, dataObject);
|
||||||
|
|
||||||
|
// const Tag = formComponentsMap[props.conf.__config__.tag];
|
||||||
|
|
||||||
|
// return () => (
|
||||||
|
// <Tag
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children}
|
||||||
|
// </Tag>
|
||||||
|
// );
|
||||||
|
// },
|
||||||
render() {
|
render() {
|
||||||
const dataObject = makeDataObject();
|
const dataObject = makeDataObject();
|
||||||
const confClone = deepClone(this.conf);
|
const confClone = deepClone(this.$props.conf);
|
||||||
|
|
||||||
// const children = [this.$slots.default] || [];
|
|
||||||
const children = [];
|
const children = [];
|
||||||
// 如果slots文件夹存在与当前tag同名的文件,则执行文件中的代码
|
// 如果slots文件夹存在与当前tag同名的文件,则执行文件中的代码
|
||||||
mountSlotFiles(h, confClone, children);
|
mountSlotFiles(confClone, children);
|
||||||
|
|
||||||
// 将字符串类型的事件,发送为消息
|
// 将字符串类型的事件,发送为消息
|
||||||
emitEvents.call(this, confClone);
|
emitEvents.call(this, confClone);
|
||||||
|
|
||||||
// 将json表单配置转化为vue render可以识别的 “数据对象(dataObject)”
|
// 将json表单配置转化为vue render可以识别的 “数据对象(dataObject)”
|
||||||
buildDataObject.call(this, confClone, dataObject);
|
buildDataObject.call(this, confClone, dataObject);
|
||||||
console.log(dataObject);
|
console.log(dataObject);
|
||||||
// return () => h("el-input", dataObject.attrs);
|
const Tag = formComponentsMap[this.$props.conf.__config__.tag];
|
||||||
|
|
||||||
const Tag = formComponentsMap[this.conf.__config__.tag];
|
|
||||||
return (
|
return (
|
||||||
<Tag
|
<Tag
|
||||||
{...dataObject.attrs}
|
{...dataObject.attrs}
|
||||||
on={dataObject.on}
|
on={dataObject.on}
|
||||||
modelValue={confClone.__config__.defaultValue}
|
v-model={this.$props.conf.__config__.defaultValue}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{tag == "el-input" ? (
|
|
||||||
<el-input
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</el-input>
|
|
||||||
) : tag == "el-input-number" ? (
|
|
||||||
<el-input-number
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</el-input-number>
|
|
||||||
) : tag == "el-slider" ? (
|
|
||||||
<el-slider
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</el-slider>
|
|
||||||
) : tag == "el-time-picker" ? (
|
|
||||||
<el-date-picker
|
|
||||||
type="datetimerange"
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
/>
|
|
||||||
) : tag === "el-switch" ? (
|
|
||||||
<el-switch
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
></el-switch>
|
|
||||||
) : tag === "el-color-picker" ? (
|
|
||||||
<el-color-picker
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
></el-color-picker>
|
|
||||||
) : tag === "el-button" ? (
|
|
||||||
<el-button
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
>
|
|
||||||
{children[1]}
|
|
||||||
</el-button>
|
|
||||||
) : tag === "el-select" ? (
|
|
||||||
<el-select
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</el-select>
|
|
||||||
) : tag === "el-date-picker" ? (
|
|
||||||
<el-date-picker
|
|
||||||
{...dataObject.attrs}
|
|
||||||
on={dataObject.on}
|
|
||||||
modelValue={confClone.__config__.defaultValue}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</el-date-picker>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
// render() {
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// {tag == "el-input" ? (
|
||||||
|
// <el-input
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children}
|
||||||
|
// </el-input>
|
||||||
|
// ) : tag == "el-input-number" ? (
|
||||||
|
// <el-input-number
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children}
|
||||||
|
// </el-input-number>
|
||||||
|
// ) : tag == "el-slider" ? (
|
||||||
|
// <el-slider
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children}
|
||||||
|
// </el-slider>
|
||||||
|
// ) : tag == "el-time-picker" ? (
|
||||||
|
// <el-date-picker
|
||||||
|
// type="datetimerange"
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// />
|
||||||
|
// ) : tag === "el-switch" ? (
|
||||||
|
// <el-switch
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// ></el-switch>
|
||||||
|
// ) : tag === "el-color-picker" ? (
|
||||||
|
// <el-color-picker
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// ></el-color-picker>
|
||||||
|
// ) : tag === "el-button" ? (
|
||||||
|
// <el-button
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children[1]}
|
||||||
|
// </el-button>
|
||||||
|
// ) : tag === "el-select" ? (
|
||||||
|
// <el-select
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children}
|
||||||
|
// </el-select>
|
||||||
|
// ) : tag === "el-date-picker" ? (
|
||||||
|
// <el-date-picker
|
||||||
|
// {...dataObject.attrs}
|
||||||
|
// on={dataObject.on}
|
||||||
|
// modelValue={confClone.__config__.defaultValue}
|
||||||
|
// >
|
||||||
|
// {children}
|
||||||
|
// </el-date-picker>
|
||||||
|
// ) : null}
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
// },
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
default(h, conf, key) {
|
default(conf, key) {
|
||||||
return conf.__slot__[key]
|
return conf.__slot__[key];
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
export default {
|
export default {
|
||||||
options(h, conf, key) {
|
options(conf, key) {
|
||||||
const list = []
|
const list = [];
|
||||||
conf.__slot__.options.forEach(item => {
|
conf.__slot__.options.forEach((item) => {
|
||||||
if (conf.__config__.optionType === 'button') {
|
if (conf.__config__.optionType === "button") {
|
||||||
list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>)
|
list.push(
|
||||||
|
<el-checkbox-button label={item.value}>
|
||||||
|
{item.label}
|
||||||
|
</el-checkbox-button>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>)
|
list.push(
|
||||||
|
<el-checkbox label={item.value} border={conf.border}>
|
||||||
|
{item.label}
|
||||||
|
</el-checkbox>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
return list
|
return list;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
export default {
|
export default {
|
||||||
prepend(h, conf, key) {
|
prepend(conf, key) {
|
||||||
return <template slot="prepend">{conf.__slot__[key]}</template>
|
return <template slot="prepend">{conf.__slot__[key]}</template>;
|
||||||
},
|
},
|
||||||
append(h, conf, key) {
|
append(conf, key) {
|
||||||
return <template slot="append">{conf.__slot__[key]}</template>
|
return <template slot="append">{conf.__slot__[key]}</template>;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
export default {
|
export default {
|
||||||
options(h, conf, key) {
|
options(conf, key) {
|
||||||
const list = []
|
const list = [];
|
||||||
conf.__slot__.options.forEach(item => {
|
conf.__slot__.options.forEach((item) => {
|
||||||
if (conf.__config__.optionType === 'button') {
|
if (conf.__config__.optionType === "button") {
|
||||||
list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>)
|
list.push(
|
||||||
|
<el-radio-button label={item.value}>{item.label}</el-radio-button>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>)
|
list.push(
|
||||||
|
<el-radio label={item.value} border={conf.border}>
|
||||||
|
{item.label}
|
||||||
|
</el-radio>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
return list
|
return list;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export default {
|
export default {
|
||||||
options(h, conf, key) {
|
options(conf, key) {
|
||||||
const list = [];
|
const list = [];
|
||||||
conf.__slot__.options.forEach((item) => {
|
conf.__slot__.options.forEach((item) => {
|
||||||
list.push(
|
list.push(
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
export default {
|
export default {
|
||||||
'list-type': (h, conf, key) => {
|
"list-type": (conf, key) => {
|
||||||
const list = []
|
const list = [];
|
||||||
const config = conf.__config__
|
const config = conf.__config__;
|
||||||
if (conf['list-type'] === 'picture-card') {
|
if (conf["list-type"] === "picture-card") {
|
||||||
list.push(<i class="el-icon-plus"></i>)
|
list.push(<i class="el-icon-plus"></i>);
|
||||||
} else {
|
} else {
|
||||||
list.push(<el-button size="small" type="primary" icon="el-icon-upload">{config.buttonText}</el-button>)
|
list.push(
|
||||||
|
<el-button size="small" type="primary" icon="el-icon-upload">
|
||||||
|
{config.buttonText}
|
||||||
|
</el-button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (config.showTip) {
|
if (config.showTip) {
|
||||||
list.push(
|
list.push(
|
||||||
<div slot="tip" class="el-upload__tip">只能上传不超过 {config.fileSize}{config.sizeUnit} 的{conf.accept}文件</div>
|
<div slot="tip" class="el-upload__tip">
|
||||||
)
|
只能上传不超过 {config.fileSize}
|
||||||
|
{config.sizeUnit} 的{conf.accept}文件
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return list
|
return list;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
@ -22,7 +22,6 @@ export default function loadBeautifier(cb) {
|
|||||||
loadScript(beautifierUrl, () => {
|
loadScript(beautifierUrl, () => {
|
||||||
loading.close();
|
loading.close();
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
console.log(beautifier);
|
|
||||||
beautifierObj = beautifier;
|
beautifierObj = beautifier;
|
||||||
cb(beautifierObj);
|
cb(beautifierObj);
|
||||||
});
|
});
|
||||||
|
@ -5,16 +5,15 @@
|
|||||||
width="500px"
|
width="500px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:modal-append-to-body="false"
|
:modal-append-to-body="false"
|
||||||
v-on="$listeners"
|
|
||||||
@open="onOpen"
|
@open="onOpen"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
>
|
>
|
||||||
<el-row :gutter="15">
|
<el-row :gutter="15">
|
||||||
<el-form
|
<el-form
|
||||||
ref="elForm"
|
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
size="medium"
|
ref="elFormRef"
|
||||||
|
size="default"
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
>
|
>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@ -31,76 +30,116 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="showFileName" label="文件名" prop="fileName">
|
<el-form-item v-if="showFileName" label="文件名" prop="fileName">
|
||||||
<el-input v-model="formData.fileName" placeholder="请输入文件名" clearable />
|
<el-input
|
||||||
|
v-model="formData.fileName"
|
||||||
|
placeholder="请输入文件名"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<!-- <el-form
|
||||||
|
ref="elForm"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
size="default"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="生成类型" prop="type">
|
||||||
|
<el-radio-group v-model="formData.type">
|
||||||
|
<el-radio-button
|
||||||
|
v-for="(item, index) in typeOptions"
|
||||||
|
:key="index"
|
||||||
|
:label="item.value"
|
||||||
|
:disabled="item.disabled"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="showFileName" label="文件名" prop="fileName">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.fileName"
|
||||||
|
placeholder="请输入文件名"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-form> -->
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
<el-button @click="close">
|
<el-button @click="close"> 取消 </el-button>
|
||||||
取消
|
<el-button type="primary" @click="handleConfirm"> 确定 </el-button>
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="handleConfirm">
|
|
||||||
确定
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, toRefs } from "vue";
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "confirm"]);
|
||||||
|
const props = defineProps(["showFileName"]);
|
||||||
|
|
||||||
|
const { showFileName } = toRefs(props);
|
||||||
|
const data = reactive({
|
||||||
|
formData: {
|
||||||
|
fileName: undefined,
|
||||||
|
type: "file",
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
fileName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请输入文件名",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "生成类型不能为空",
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { formData, rules } = toRefs(data);
|
||||||
|
const elFormRef = ref();
|
||||||
|
const typeOptions = ref([
|
||||||
|
{
|
||||||
|
label: "页面",
|
||||||
|
value: "file",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "弹窗",
|
||||||
|
value: "dialog",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const onOpen = () => {
|
||||||
|
if (showFileName.value) {
|
||||||
|
formData.value.fileName = `${+new Date()}.vue`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onClose = () => {};
|
||||||
|
const close = (e) => {
|
||||||
|
emit("update:modelValue", false);
|
||||||
|
};
|
||||||
|
const handleConfirm = () => {
|
||||||
|
elFormRef.value.validate((valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
emit("confirm", { ...formData.value });
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: ['showFileName'],
|
};
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
formData: {
|
|
||||||
fileName: undefined,
|
|
||||||
type: 'file'
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
fileName: [{
|
|
||||||
required: true,
|
|
||||||
message: '请输入文件名',
|
|
||||||
trigger: 'blur'
|
|
||||||
}],
|
|
||||||
type: [{
|
|
||||||
required: true,
|
|
||||||
message: '生成类型不能为空',
|
|
||||||
trigger: 'change'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
typeOptions: [{
|
|
||||||
label: '页面',
|
|
||||||
value: 'file'
|
|
||||||
}, {
|
|
||||||
label: '弹窗',
|
|
||||||
value: 'dialog'
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
},
|
|
||||||
watch: {},
|
|
||||||
mounted() {},
|
|
||||||
methods: {
|
|
||||||
onOpen() {
|
|
||||||
if (this.showFileName) {
|
|
||||||
this.formData.fileName = `${+new Date()}.vue`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onClose() {
|
|
||||||
},
|
|
||||||
close(e) {
|
|
||||||
this.$emit('update:visible', false)
|
|
||||||
},
|
|
||||||
handleConfirm() {
|
|
||||||
this.$refs.elForm.validate(valid => {
|
|
||||||
if (!valid) return
|
|
||||||
this.$emit('confirm', { ...this.formData })
|
|
||||||
this.close()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -37,13 +37,13 @@ const components = {
|
|||||||
const layouts = {
|
const layouts = {
|
||||||
colFormItem(
|
colFormItem(
|
||||||
// h,
|
// h,
|
||||||
currentItem,
|
currentItem
|
||||||
index,
|
// index,
|
||||||
list
|
// list
|
||||||
) {
|
) {
|
||||||
const { onActiveItem } = this.$attrs;
|
const { onActiveItem } = this.$attrs;
|
||||||
const config = currentItem.__config__;
|
const config = currentItem.__config__;
|
||||||
console.log(arguments, "argu");
|
// console.log(arguments, "argu");
|
||||||
const child = renderChildren.apply(this, arguments);
|
const child = renderChildren.apply(this, arguments);
|
||||||
let className =
|
let className =
|
||||||
this.activeId === config.formId
|
this.activeId === config.formId
|
||||||
@ -53,7 +53,7 @@ const layouts = {
|
|||||||
className += " unfocus-bordered";
|
className += " unfocus-bordered";
|
||||||
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null;
|
let labelWidth = config.labelWidth ? `${config.labelWidth}px` : null;
|
||||||
if (config.showLabel === false) labelWidth = "0";
|
if (config.showLabel === false) labelWidth = "0";
|
||||||
console.log(child);
|
// console.log(child);
|
||||||
return (
|
return (
|
||||||
<el-col
|
<el-col
|
||||||
span={config.span}
|
span={config.span}
|
||||||
@ -72,10 +72,10 @@ const layouts = {
|
|||||||
key={config.renderKey}
|
key={config.renderKey}
|
||||||
conf={currentItem}
|
conf={currentItem}
|
||||||
onInput={(event) => {
|
onInput={(event) => {
|
||||||
console.log(event);
|
// console.log(event);
|
||||||
// console.log(this.currentItem.__config__.defaultValue);
|
// // console.log(this.currentItem.__config__.defaultValue);
|
||||||
// this.$set(config, "defaultValue", event);
|
// this.$set(config, "defaultValue", event);
|
||||||
// console.log(this.currentItem.__config__.defaultValue);
|
// // console.log(this.currentItem.__config__.defaultValue);
|
||||||
this.currentItem.__config__.defaultValue = event;
|
this.currentItem.__config__.defaultValue = event;
|
||||||
// config.defaultValue = event;
|
// config.defaultValue = event;
|
||||||
// config.defaultValue = event;
|
// config.defaultValue = event;
|
||||||
@ -90,12 +90,13 @@ const layouts = {
|
|||||||
},
|
},
|
||||||
rowFormItem(
|
rowFormItem(
|
||||||
// h,
|
// h,
|
||||||
currentItem,
|
currentItem
|
||||||
index,
|
// index,
|
||||||
list
|
// list
|
||||||
) {
|
) {
|
||||||
const { onActiveItem } = this.$attrs;
|
const { onActiveItem } = this.$attrs;
|
||||||
const config = currentItem.__config__;
|
const config = currentItem.__config__;
|
||||||
|
// console.log(config);
|
||||||
const className =
|
const className =
|
||||||
this.activeId === config.formId
|
this.activeId === config.formId
|
||||||
? "drawing-row-item active-from-item"
|
? "drawing-row-item active-from-item"
|
||||||
@ -113,7 +114,6 @@ const layouts = {
|
|||||||
</el-row>
|
</el-row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
console.log(child, "row");
|
|
||||||
return (
|
return (
|
||||||
<el-col span={config.span}>
|
<el-col span={config.span}>
|
||||||
<el-row
|
<el-row
|
||||||
@ -127,6 +127,11 @@ const layouts = {
|
|||||||
<span class="component-name">{config.componentName}</span>
|
<span class="component-name">{config.componentName}</span>
|
||||||
<draggable
|
<draggable
|
||||||
list={config.children || []}
|
list={config.children || []}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
display: "flex",
|
||||||
|
}}
|
||||||
animation={340}
|
animation={340}
|
||||||
group="componentsGroup"
|
group="componentsGroup"
|
||||||
class="drag-wrapper"
|
class="drag-wrapper"
|
||||||
@ -134,7 +139,18 @@ const layouts = {
|
|||||||
draggable
|
draggable
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
item: () => child,
|
item: ({ element, index }) => {
|
||||||
|
const layout = layouts[element.__config__.layout];
|
||||||
|
if (layout) {
|
||||||
|
return layout.call(
|
||||||
|
this,
|
||||||
|
element,
|
||||||
|
index,
|
||||||
|
element.__config__.children
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return layoutIsNotFound.call(this);
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
</draggable>
|
</draggable>
|
||||||
{components.itemBtns.apply(this, arguments)}
|
{components.itemBtns.apply(this, arguments)}
|
||||||
@ -144,9 +160,9 @@ const layouts = {
|
|||||||
},
|
},
|
||||||
raw(
|
raw(
|
||||||
// h,
|
// h,
|
||||||
currentItem,
|
currentItem
|
||||||
index,
|
// index,
|
||||||
list
|
// list
|
||||||
) {
|
) {
|
||||||
const config = currentItem.__config__;
|
const config = currentItem.__config__;
|
||||||
const child = renderChildren.apply(this, arguments);
|
const child = renderChildren.apply(this, arguments);
|
||||||
@ -155,8 +171,9 @@ const layouts = {
|
|||||||
key={config.renderKey}
|
key={config.renderKey}
|
||||||
conf={currentItem}
|
conf={currentItem}
|
||||||
onInput={(event) => {
|
onInput={(event) => {
|
||||||
// this.$set(config, "defaultValue", event);
|
// console.log(event, "oninput");
|
||||||
// console.log(this.currentItem.__config__.defaultValue);
|
// // this.$set(config, "defaultValue", event);
|
||||||
|
// // console.log(this.currentItem.__config__.defaultValue);
|
||||||
this.currentItem.__config__.defaultValue = event;
|
this.currentItem.__config__.defaultValue = event;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -167,20 +184,21 @@ const layouts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function renderChildren(
|
function renderChildren(
|
||||||
// h,
|
// // h,
|
||||||
currentItem,
|
currentItem
|
||||||
index,
|
// // index,
|
||||||
list
|
// // list
|
||||||
) {
|
) {
|
||||||
const config = currentItem.__config__;
|
const config = currentItem.__config__;
|
||||||
console.log(config, "config");
|
// // console.log(config, "config");
|
||||||
if (!Array.isArray(config.children)) return null;
|
if (!Array.isArray(config.children)) return null;
|
||||||
return config.children.map((el, i) => {
|
return config.children.map((el, i) => {
|
||||||
const layout = layouts[el.__config__.layout];
|
const layout = layouts[el.__config__.layout];
|
||||||
|
// console.log(el.__config__.layout, `row's child`);
|
||||||
if (layout) {
|
if (layout) {
|
||||||
return layout.call(
|
return layout.call(
|
||||||
this,
|
this,
|
||||||
// h,
|
// // h,
|
||||||
el,
|
el,
|
||||||
i,
|
i,
|
||||||
config.children
|
config.children
|
||||||
@ -207,14 +225,14 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
// console.log(this.currentItem.__config__.layout);
|
// // console.log(this.currentItem.__config__.layout);
|
||||||
const layout = layouts[this.currentItem.__config__.layout];
|
const layout = layouts[this.currentItem.__config__.layout];
|
||||||
// console.log(this.currentItem);
|
// // console.log(this.currentItem);
|
||||||
console.log(layout, "layout");
|
// // console.log(layout, "layout");
|
||||||
if (layout) {
|
if (layout) {
|
||||||
return layout.call(
|
return layout.call(
|
||||||
this,
|
this,
|
||||||
// h,
|
// // h,
|
||||||
this.currentItem,
|
this.currentItem,
|
||||||
this.index,
|
this.index,
|
||||||
this.drawingList
|
this.drawingList
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-drawer
|
<el-drawer v-bind="$attrs" @opened="onOpen" @close="onClose">
|
||||||
v-bind="$attrs"
|
|
||||||
v-on="$listeners"
|
|
||||||
@opened="onOpen"
|
|
||||||
@close="onClose"
|
|
||||||
>
|
|
||||||
<div style="height: 100%">
|
<div style="height: 100%">
|
||||||
<el-row style="height: 100%; overflow: auto">
|
<el-row style="height: 100%; overflow: auto">
|
||||||
<el-col :md="24" :lg="12" class="left-editor">
|
<el-col :md="24" :lg="12" class="left-editor">
|
||||||
@ -17,22 +12,34 @@
|
|||||||
<el-tabs v-model="activeTab" type="card" class="editor-tabs">
|
<el-tabs v-model="activeTab" type="card" class="editor-tabs">
|
||||||
<el-tab-pane name="html">
|
<el-tab-pane name="html">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<i v-if="activeTab === 'html'" class="el-icon-edit" />
|
<el-icon>
|
||||||
<i v-else class="el-icon-document" />
|
<Edit v-if="activeTab === 'html'" />
|
||||||
|
<Document v-else />
|
||||||
|
</el-icon>
|
||||||
|
<!-- <i v-if="activeTab === 'html'" class="el-icon-edit" />
|
||||||
|
<i v-else class="el-icon-document" /> -->
|
||||||
template
|
template
|
||||||
</span>
|
</span>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane name="js">
|
<el-tab-pane name="js">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<i v-if="activeTab === 'js'" class="el-icon-edit" />
|
<el-icon>
|
||||||
<i v-else class="el-icon-document" />
|
<Edit v-if="activeTab === 'js'" />
|
||||||
|
<Document v-else />
|
||||||
|
</el-icon>
|
||||||
|
<!-- <i v-if="activeTab === 'js'" class="el-icon-edit" />
|
||||||
|
<i v-else class="el-icon-document" /> -->
|
||||||
script
|
script
|
||||||
</span>
|
</span>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane name="css">
|
<el-tab-pane name="css">
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
<i v-if="activeTab === 'css'" class="el-icon-edit" />
|
<el-icon>
|
||||||
<i v-else class="el-icon-document" />
|
<Edit v-if="activeTab === 'css'" />
|
||||||
|
<Document v-else />
|
||||||
|
</el-icon>
|
||||||
|
<!-- <i v-if="activeTab === 'css'" class="el-icon-edit" />
|
||||||
|
<i v-else class="el-icon-document" /> -->
|
||||||
css
|
css
|
||||||
</span>
|
</span>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -65,7 +72,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="bar-btn delete-btn"
|
class="bar-btn delete-btn"
|
||||||
@click="$emit('update:visible', false)"
|
@click="$emit('update:modelValue', false)"
|
||||||
>
|
>
|
||||||
<i class="el-icon-circle-close" />
|
<i class="el-icon-circle-close" />
|
||||||
关闭
|
关闭
|
||||||
@ -95,7 +102,8 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
|
||||||
|
<script setup>
|
||||||
import { parse } from "@babel/parser";
|
import { parse } from "@babel/parser";
|
||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import { saveAs } from "file-saver";
|
import { saveAs } from "file-saver";
|
||||||
@ -111,7 +119,9 @@ import { exportDefault, beautifierConf, titleCase } from "@/utils/index";
|
|||||||
import ResourceDialog from "./ResourceDialog";
|
import ResourceDialog from "./ResourceDialog";
|
||||||
import loadMonaco from "@/utils/loadMonaco";
|
import loadMonaco from "@/utils/loadMonaco";
|
||||||
import loadBeautifier from "@/utils/loadBeautifier";
|
import loadBeautifier from "@/utils/loadBeautifier";
|
||||||
|
import { computed, onBeforeUnmount, onMounted } from "vue";
|
||||||
|
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
|
||||||
|
import { Document, Edit } from "@element-plus/icons-vue";
|
||||||
const editorObj = {
|
const editorObj = {
|
||||||
html: null,
|
html: null,
|
||||||
js: null,
|
js: null,
|
||||||
@ -123,193 +133,177 @@ const mode = {
|
|||||||
css: "css",
|
css: "css",
|
||||||
};
|
};
|
||||||
let beautifier;
|
let beautifier;
|
||||||
let monaco;
|
// let monaco;
|
||||||
|
const props = defineProps(["formData", "generateConf"]);
|
||||||
|
const { formData, generateConf } = toRefs(props);
|
||||||
|
const activeTab = ref("html");
|
||||||
|
const htmlCode = ref("");
|
||||||
|
const jsCode = ref("");
|
||||||
|
const cssCode = ref("");
|
||||||
|
const codeFrame = ref("");
|
||||||
|
const isIframeLoaded = ref(false);
|
||||||
|
const isInitcode = ref(false); // 保证open后两个异步只执行一次runcode
|
||||||
|
const isRefreshCode = ref(false); // 每次打开都需要重新刷新代码
|
||||||
|
const resourceVisible = ref(false);
|
||||||
|
const scripts = ref([]);
|
||||||
|
const links = ref([]);
|
||||||
|
const monaco = ref(null);
|
||||||
|
|
||||||
export default {
|
const preventDefaultSave = (e) => {
|
||||||
components: { ResourceDialog },
|
if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
|
||||||
props: ["formData", "generateConf"],
|
e.preventDefault();
|
||||||
data() {
|
}
|
||||||
return {
|
|
||||||
activeTab: "html",
|
|
||||||
htmlCode: "",
|
|
||||||
jsCode: "",
|
|
||||||
cssCode: "",
|
|
||||||
codeFrame: "",
|
|
||||||
isIframeLoaded: false,
|
|
||||||
isInitcode: false, // 保证open后两个异步只执行一次runcode
|
|
||||||
isRefreshCode: false, // 每次打开都需要重新刷新代码
|
|
||||||
resourceVisible: false,
|
|
||||||
scripts: [],
|
|
||||||
links: [],
|
|
||||||
monaco: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
resources() {
|
|
||||||
return this.scripts.concat(this.links);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {},
|
|
||||||
created() {},
|
|
||||||
mounted() {
|
|
||||||
window.addEventListener("keydown", this.preventDefaultSave);
|
|
||||||
const clipboard = new ClipboardJS(".copy-btn", {
|
|
||||||
text: (trigger) => {
|
|
||||||
const codeStr = this.generateCode();
|
|
||||||
this.$notify({
|
|
||||||
title: "成功",
|
|
||||||
message: "代码已复制到剪切板,可粘贴。",
|
|
||||||
type: "success",
|
|
||||||
});
|
|
||||||
return codeStr;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
clipboard.on("error", (e) => {
|
|
||||||
this.$message.error("代码复制失败");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
window.removeEventListener("keydown", this.preventDefaultSave);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
preventDefaultSave(e) {
|
|
||||||
if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onOpen() {
|
|
||||||
const { type } = this.generateConf;
|
|
||||||
this.htmlCode = makeUpHtml(this.formData, type);
|
|
||||||
this.jsCode = makeUpJs(this.formData, type);
|
|
||||||
this.cssCode = makeUpCss(this.formData);
|
|
||||||
|
|
||||||
loadBeautifier((btf) => {
|
|
||||||
beautifier = btf;
|
|
||||||
this.htmlCode = beautifier.html(this.htmlCode, beautifierConf.html);
|
|
||||||
this.jsCode = beautifier.js(this.jsCode, beautifierConf.js);
|
|
||||||
this.cssCode = beautifier.css(this.cssCode, beautifierConf.html);
|
|
||||||
|
|
||||||
loadMonaco((val) => {
|
|
||||||
monaco = val;
|
|
||||||
this.setEditorValue("editorHtml", "html", this.htmlCode);
|
|
||||||
this.setEditorValue("editorJs", "js", this.jsCode);
|
|
||||||
this.setEditorValue("editorCss", "css", this.cssCode);
|
|
||||||
if (!this.isInitcode) {
|
|
||||||
this.isRefreshCode = true;
|
|
||||||
this.isIframeLoaded && (this.isInitcode = true) && this.runCode();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onClose() {
|
|
||||||
this.isInitcode = false;
|
|
||||||
this.isRefreshCode = false;
|
|
||||||
},
|
|
||||||
iframeLoad() {
|
|
||||||
if (!this.isInitcode) {
|
|
||||||
this.isIframeLoaded = true;
|
|
||||||
this.isRefreshCode && (this.isInitcode = true) && this.runCode();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setEditorValue(id, type, codeStr) {
|
|
||||||
if (editorObj[type]) {
|
|
||||||
editorObj[type].setValue(codeStr);
|
|
||||||
} else {
|
|
||||||
editorObj[type] = monaco.editor.create(document.getElementById(id), {
|
|
||||||
value: codeStr,
|
|
||||||
theme: "vs-dark",
|
|
||||||
language: mode[type],
|
|
||||||
automaticLayout: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// ctrl + s 刷新
|
|
||||||
editorObj[type].onKeyDown((e) => {
|
|
||||||
if (e.keyCode === 49 && (e.metaKey || e.ctrlKey)) {
|
|
||||||
this.runCode();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
runCode() {
|
|
||||||
const jsCodeStr = editorObj.js.getValue();
|
|
||||||
try {
|
|
||||||
const ast = parse(jsCodeStr, { sourceType: "module" });
|
|
||||||
const astBody = ast.program.body;
|
|
||||||
if (astBody.length > 1) {
|
|
||||||
this.$confirm(
|
|
||||||
"js格式不能识别,仅支持修改export default的对象内容",
|
|
||||||
"提示",
|
|
||||||
{
|
|
||||||
type: "warning",
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (astBody[0].type === "ExportDefaultDeclaration") {
|
|
||||||
const postData = {
|
|
||||||
type: "refreshFrame",
|
|
||||||
data: {
|
|
||||||
generateConf: this.generateConf,
|
|
||||||
html: editorObj.html.getValue(),
|
|
||||||
js: jsCodeStr.replace(exportDefault, ""),
|
|
||||||
css: editorObj.css.getValue(),
|
|
||||||
scripts: this.scripts,
|
|
||||||
links: this.links,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$refs.previewPage.contentWindow.postMessage(
|
|
||||||
postData,
|
|
||||||
location.origin
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.$message.error("请使用export default");
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.$message.error(`js错误:${err}`);
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
generateCode() {
|
|
||||||
const html = vueTemplate(editorObj.html.getValue());
|
|
||||||
const script = vueScript(editorObj.js.getValue());
|
|
||||||
const css = cssStyle(editorObj.css.getValue());
|
|
||||||
return beautifier.html(html + script + css, beautifierConf.html);
|
|
||||||
},
|
|
||||||
exportFile() {
|
|
||||||
this.$prompt("文件名:", "导出文件", {
|
|
||||||
inputValue: `${+new Date()}.vue`,
|
|
||||||
closeOnClickModal: false,
|
|
||||||
inputPlaceholder: "请输入文件名",
|
|
||||||
}).then(({ value }) => {
|
|
||||||
if (!value) value = `${+new Date()}.vue`;
|
|
||||||
const codeStr = this.generateCode();
|
|
||||||
const blob = new Blob([codeStr], { type: "text/plain;charset=utf-8" });
|
|
||||||
saveAs(blob, value);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showResource() {
|
|
||||||
this.resourceVisible = true;
|
|
||||||
},
|
|
||||||
setResource(arr) {
|
|
||||||
const scripts = [];
|
|
||||||
const links = [];
|
|
||||||
if (Array.isArray(arr)) {
|
|
||||||
arr.forEach((item) => {
|
|
||||||
if (item.endsWith(".css")) {
|
|
||||||
links.push(item);
|
|
||||||
} else {
|
|
||||||
scripts.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.scripts = scripts;
|
|
||||||
this.links = links;
|
|
||||||
} else {
|
|
||||||
this.scripts = [];
|
|
||||||
this.links = [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
const onOpen = () => {
|
||||||
|
const { type } = generateConf.value;
|
||||||
|
htmlCode.value = makeUpHtml(formData.value, type);
|
||||||
|
jsCode.value = makeUpJs(formData.value, type);
|
||||||
|
cssCode.value = makeUpCss(formData.value);
|
||||||
|
|
||||||
|
loadBeautifier((btf) => {
|
||||||
|
beautifier = btf;
|
||||||
|
htmlCode.value = beautifier.html(htmlCode.value, beautifierConf.html);
|
||||||
|
jsCode.value = beautifier.js(jsCode.value, beautifierConf.js);
|
||||||
|
cssCode.value = beautifier.css(cssCode.value, beautifierConf.html);
|
||||||
|
|
||||||
|
loadMonaco((val) => {
|
||||||
|
monaco.value = val;
|
||||||
|
setEditorValue("editorHtml", "html", htmlCode.value);
|
||||||
|
setEditorValue("editorJs", "js", jsCode.value);
|
||||||
|
setEditorValue("editorCss", "css", cssCode.value);
|
||||||
|
if (!isInitcode.value) {
|
||||||
|
isRefreshCode.value = true;
|
||||||
|
isIframeLoaded.value && (isInitcode.value = true) && runCode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const onClose = () => {
|
||||||
|
isInitcode.value = false;
|
||||||
|
isRefreshCode.value = false;
|
||||||
|
};
|
||||||
|
const iframeLoad = () => {
|
||||||
|
if (!isInitcode.value) {
|
||||||
|
isIframeLoaded.value = true;
|
||||||
|
isRefreshCode.value && (isInitcode.value = true) && runCode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const setEditorValue = (id, type, codeStr) => {
|
||||||
|
if (editorObj[type]) {
|
||||||
|
editorObj[type].setValue(codeStr);
|
||||||
|
} else {
|
||||||
|
editorObj[type] = monaco.value.editor.create(document.getElementById(id), {
|
||||||
|
value: codeStr,
|
||||||
|
theme: "vs-dark",
|
||||||
|
language: mode[type],
|
||||||
|
automaticLayout: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ctrl + s 刷新
|
||||||
|
editorObj[type].onKeyDown((e) => {
|
||||||
|
if (e.keyCode === 49 && (e.metaKey || e.ctrlKey)) {
|
||||||
|
runCode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const previewPage = ref();
|
||||||
|
const runCode = () => {
|
||||||
|
const jsCodeStr = editorObj.js.getValue();
|
||||||
|
try {
|
||||||
|
const ast = parse(jsCodeStr, { sourceType: "module" });
|
||||||
|
const astBody = ast.program.body;
|
||||||
|
if (astBody.length > 1) {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
"js格式不能识别,仅支持修改export default的对象内容",
|
||||||
|
"提示",
|
||||||
|
{
|
||||||
|
type: "warning",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (astBody[0].type === "ExportDefaultDeclaration") {
|
||||||
|
const postData = {
|
||||||
|
type: "refreshFrame",
|
||||||
|
data: {
|
||||||
|
generateConf: generateConf.value,
|
||||||
|
html: editorObj.html.getValue(),
|
||||||
|
js: jsCodeStr.replace(exportDefault, ""),
|
||||||
|
css: editorObj.css.getValue(),
|
||||||
|
scripts: scripts.value,
|
||||||
|
links: links.value,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
previewPage.value.contentWindow.postMessage(postData, location.origin);
|
||||||
|
} else {
|
||||||
|
ElMessage.error("请使用export default");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage.error(`js错误:${err}`);
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const generateCode = () => {
|
||||||
|
const html = vueTemplate(editorObj.html.getValue());
|
||||||
|
const script = vueScript(editorObj.js.getValue());
|
||||||
|
const css = cssStyle(editorObj.css.getValue());
|
||||||
|
return beautifier.html(html + script + css, beautifierConf.html);
|
||||||
|
};
|
||||||
|
const exportFile = () => {
|
||||||
|
ElMessageBox.prompt("文件名:", "导出文件", {
|
||||||
|
inputValue: `${+new Date()}.vue`,
|
||||||
|
closeOnClickModal: false,
|
||||||
|
inputPlaceholder: "请输入文件名",
|
||||||
|
}).then(({ value }) => {
|
||||||
|
if (!value) value = `${+new Date()}.vue`;
|
||||||
|
const codeStr = generateCode();
|
||||||
|
const blob = new Blob([codeStr], { type: "text/plain;charset=utf-8" });
|
||||||
|
saveAs(blob, value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const showResource = () => {
|
||||||
|
resourceVisible.value = true;
|
||||||
|
};
|
||||||
|
const setResource = (arr) => {
|
||||||
|
const _scripts = [];
|
||||||
|
const _links = [];
|
||||||
|
if (Array.isArray(arr)) {
|
||||||
|
arr.forEach((item) => {
|
||||||
|
if (item.endsWith(".css")) {
|
||||||
|
links.push(item);
|
||||||
|
} else {
|
||||||
|
scripts.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scripts.value = _scripts;
|
||||||
|
links.value = _links;
|
||||||
|
} else {
|
||||||
|
scripts.value = [];
|
||||||
|
links.value = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const resources = computed(() => scripts.value.concat(links.value));
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener("keydown", preventDefaultSave);
|
||||||
|
const clipboard = new ClipboardJS(".copy-btn", {
|
||||||
|
text: (trigger) => {
|
||||||
|
const codeStr = generateCode();
|
||||||
|
ElNotification({
|
||||||
|
title: "成功",
|
||||||
|
message: "代码已复制到剪切板,可粘贴。",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
return codeStr;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
clipboard.on("error", (e) => {
|
||||||
|
ElMessage.error("代码复制失败");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener("keydown", preventDefaultSave);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -59,7 +59,6 @@ const preventDefaultSave = (e) => {
|
|||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
loadBeautifier((btf) => {
|
loadBeautifier((btf) => {
|
||||||
beautifier = btf;
|
beautifier = btf;
|
||||||
console.log(btf.js);
|
|
||||||
beautifierJson.value = beautifier.js(jsonStr.value, beautifierConf.js);
|
beautifierJson.value = beautifier.js(jsonStr.value, beautifierConf.js);
|
||||||
|
|
||||||
loadMonaco((val) => {
|
loadMonaco((val) => {
|
||||||
@ -154,7 +153,7 @@ export default {
|
|||||||
::v-deep .el-drawer__header {
|
::v-deep .el-drawer__header {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
// @include action-bar;
|
@include action-bar;
|
||||||
|
|
||||||
.json-editor {
|
.json-editor {
|
||||||
height: calc(100vh - 33px);
|
height: calc(100vh - 33px);
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
title="外部资源引用"
|
title="外部资源引用"
|
||||||
width="600px"
|
width="600px"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
v-on="$listeners"
|
|
||||||
@open="onOpen"
|
@open="onOpen"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
>
|
>
|
||||||
@ -31,45 +30,31 @@
|
|||||||
>
|
>
|
||||||
jQuery1.8.3
|
jQuery1.8.3
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button plain @click="addOne('https://unpkg.com/http-vue-loader')">
|
||||||
plain
|
|
||||||
@click="addOne('https://unpkg.com/http-vue-loader')"
|
|
||||||
>
|
|
||||||
http-vue-loader
|
http-vue-loader
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button icon="el-icon-circle-plus-outline" plain @click="addOne('')">
|
||||||
icon="el-icon-circle-plus-outline"
|
|
||||||
plain
|
|
||||||
@click="addOne('')"
|
|
||||||
>
|
|
||||||
添加其他
|
添加其他
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
<div slot="footer">
|
<div slot="footer">
|
||||||
<el-button @click="close">
|
<el-button @click="close"> 取消 </el-button>
|
||||||
取消
|
<el-button type="primary" @click="handelConfirm"> 确定 </el-button>
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="handelConfirm"
|
|
||||||
>
|
|
||||||
确定
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { deepClone } from '@/utils/index'
|
import { deepClone } from "@/utils/index";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: ['originResource'],
|
props: ["originResource"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
resources: null
|
resources: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
@ -77,40 +62,40 @@ export default {
|
|||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
onOpen() {
|
onOpen() {
|
||||||
this.resources = this.originResource.length ? deepClone(this.originResource) : ['']
|
this.resources = this.originResource.length
|
||||||
},
|
? deepClone(this.originResource)
|
||||||
onClose() {
|
: [""];
|
||||||
},
|
},
|
||||||
|
onClose() {},
|
||||||
close() {
|
close() {
|
||||||
this.$emit('update:visible', false)
|
this.$emit("update:visible", false);
|
||||||
},
|
},
|
||||||
handelConfirm() {
|
handelConfirm() {
|
||||||
const results = this.resources.filter(item => !!item) || []
|
const results = this.resources.filter((item) => !!item) || [];
|
||||||
this.$emit('save', results)
|
this.$emit("save", results);
|
||||||
this.close()
|
this.close();
|
||||||
if (results.length) {
|
if (results.length) {
|
||||||
this.resources = results
|
this.resources = results;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteOne(index) {
|
deleteOne(index) {
|
||||||
this.resources.splice(index, 1)
|
this.resources.splice(index, 1);
|
||||||
},
|
},
|
||||||
addOne(url) {
|
addOne(url) {
|
||||||
if (this.resources.indexOf(url) > -1) {
|
if (this.resources.indexOf(url) > -1) {
|
||||||
this.$message('资源已存在')
|
this.$message("资源已存在");
|
||||||
} else {
|
} else {
|
||||||
this.resources.push(url)
|
this.resources.push(url);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.add-item{
|
.add-item {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
.url-item{
|
.url-item {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -193,7 +193,7 @@
|
|||||||
label="默认值"
|
label="默认值"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
:value="setDefaultValue(activeData.__config__.defaultValue)"
|
:modelValue="setDefaultValue(activeData.__config__.defaultValue)"
|
||||||
placeholder="请输入默认值"
|
placeholder="请输入默认值"
|
||||||
@input="onDefaultValueInput"
|
@input="onDefaultValueInput"
|
||||||
/>
|
/>
|
||||||
@ -203,7 +203,7 @@
|
|||||||
label="至少应选"
|
label="至少应选"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:value="activeData.min"
|
:modelValue="activeData.min"
|
||||||
:min="0"
|
:min="0"
|
||||||
placeholder="至少应选"
|
placeholder="至少应选"
|
||||||
@input="$set(activeData, 'min', $event ? $event : undefined)"
|
@input="$set(activeData, 'min', $event ? $event : undefined)"
|
||||||
@ -214,7 +214,7 @@
|
|||||||
label="最多可选"
|
label="最多可选"
|
||||||
>
|
>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
:value="activeData.max"
|
:modelValue="activeData.max"
|
||||||
:min="0"
|
:min="0"
|
||||||
placeholder="最多可选"
|
placeholder="最多可选"
|
||||||
@input="$set(activeData, 'max', $event ? $event : undefined)"
|
@input="$set(activeData, 'max', $event ? $event : undefined)"
|
||||||
@ -394,7 +394,7 @@
|
|||||||
label="开启值"
|
label="开启值"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
:value="setDefaultValue(activeData['active-value'])"
|
:modelValue="setDefaultValue(activeData['active-value'])"
|
||||||
placeholder="请输入开启值"
|
placeholder="请输入开启值"
|
||||||
@input="onSwitchValueInput($event, 'active-value')"
|
@input="onSwitchValueInput($event, 'active-value')"
|
||||||
/>
|
/>
|
||||||
@ -404,7 +404,7 @@
|
|||||||
label="关闭值"
|
label="关闭值"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
:value="setDefaultValue(activeData['inactive-value'])"
|
:modelValue="setDefaultValue(activeData['inactive-value'])"
|
||||||
placeholder="请输入关闭值"
|
placeholder="请输入关闭值"
|
||||||
@input="onSwitchValueInput($event, 'inactive-value')"
|
@input="onSwitchValueInput($event, 'inactive-value')"
|
||||||
/>
|
/>
|
||||||
@ -545,7 +545,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="activeData.format !== undefined" label="时间格式">
|
<el-form-item v-if="activeData.format !== undefined" label="时间格式">
|
||||||
<el-input
|
<el-input
|
||||||
:value="activeData.format"
|
:modelValue="activeData.format"
|
||||||
placeholder="请输入时间格式"
|
placeholder="请输入时间格式"
|
||||||
@input="setTimeValue($event)"
|
@input="setTimeValue($event)"
|
||||||
/>
|
/>
|
||||||
@ -671,15 +671,30 @@
|
|||||||
:data="activeData.options"
|
:data="activeData.options"
|
||||||
node-key="id"
|
node-key="id"
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
:render-content="renderContent"
|
>
|
||||||
/>
|
<!-- :render-content="renderContent" -->
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<div class="custom-tree-node">
|
||||||
|
<span>{{ node.label }}</span>
|
||||||
|
<span class="node-operation">
|
||||||
|
<ElIcon @click="append(data)" title="添加">
|
||||||
|
<Plus />
|
||||||
|
</ElIcon>
|
||||||
|
|
||||||
|
<ElIcon @click="remove(node, data)" title="删除">
|
||||||
|
<Delete />
|
||||||
|
</ElIcon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
<div
|
<div
|
||||||
v-if="activeData.__config__.dataType === 'static'"
|
v-if="activeData.__config__.dataType === 'static'"
|
||||||
style="margin-left: 20px"
|
style="margin-left: 20px"
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
style="padding-bottom: 0"
|
style="padding-bottom: 0"
|
||||||
icon="el-icon-circle-plus-outline"
|
icon="circle-plus"
|
||||||
link
|
link
|
||||||
@click="addTreeItem"
|
@click="addTreeItem"
|
||||||
>
|
>
|
||||||
@ -1010,22 +1025,24 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<treeNode-dialog
|
<treeNode-dialog
|
||||||
:visible.sync="dialogVisible"
|
v-model="dialogVisible"
|
||||||
title="添加选项"
|
title="添加选项"
|
||||||
@commit="addNode"
|
@commit="addNode"
|
||||||
/>
|
/>
|
||||||
<icons-dialog
|
<icons-dialog
|
||||||
:visible.sync="iconsVisible"
|
v-model="iconsVisible"
|
||||||
:current="activeData[currentIconModel]"
|
:current="activeData[currentIconModel]"
|
||||||
@select="setIcon"
|
@select="setIcon"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Link } from "@element-plus/icons-vue";
|
import { Link, Plus } from "@element-plus/icons-vue";
|
||||||
import TreeNodeDialog from "./TreeNodeDialog.vue";
|
import TreeNodeDialog from "./TreeNodeDialog.vue";
|
||||||
import { isNumberStr } from "@/utils/index";
|
import { isNumberStr } from "@/utils/index";
|
||||||
import IconsDialog from "./IconsDialog.vue";
|
import IconsDialog from "./IconsDialog.vue";
|
||||||
|
import { getIdGlobal } from "@/utils/db";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
inputComponents,
|
inputComponents,
|
||||||
selectComponents,
|
selectComponents,
|
||||||
@ -1047,6 +1064,7 @@ const dateTimeFormat = {
|
|||||||
// const size = ref("small");
|
// const size = ref("small");
|
||||||
// 使changeRenderKey在目标组件改变时可用
|
// 使changeRenderKey在目标组件改变时可用
|
||||||
const needRerenderList = ["tinymce"];
|
const needRerenderList = ["tinymce"];
|
||||||
|
const idGlobal = ref(getIdGlobal());
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
showField: {
|
showField: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -1087,39 +1105,38 @@ const addTreeItem = () => {
|
|||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
currentNode.value = activeData.value.options;
|
currentNode.value = activeData.value.options;
|
||||||
};
|
};
|
||||||
const renderContent = (h, { node, data, store }) => {
|
|
||||||
return `<div class="custom-tree-node">
|
// const renderContent = (h, { node, data, store }) => {
|
||||||
<span>{node.label}</span>
|
// return (
|
||||||
<span class="node-operation">
|
// <div class="custom-tree-node">
|
||||||
<i
|
// <span>{node.label}</span>
|
||||||
onClick={() => this.append(data)}
|
// <span class="node-operation">
|
||||||
class="el-icon-plus"
|
// <i onClick={() => append(data)} class="el-icon-plus" title="添加"></i>
|
||||||
title="添加"
|
// <i
|
||||||
></i>
|
// onClick={() => remove(node, data)}
|
||||||
<i
|
// class="el-icon-delete"
|
||||||
onClick={() => this.remove(node, data)}
|
// title="删除"
|
||||||
class="el-icon-delete"
|
// ></i>
|
||||||
title="删除"
|
// </span>
|
||||||
></i>
|
// </div>
|
||||||
</span>
|
// );
|
||||||
</div>`;
|
// };
|
||||||
};
|
|
||||||
const append = (data) => {
|
const append = (data) => {
|
||||||
if (!data.children) {
|
if (!data.children) {
|
||||||
this.$set(data, "children", []);
|
data.children = [];
|
||||||
}
|
}
|
||||||
this.dialogVisible = true;
|
dialogVisible.value = true;
|
||||||
this.currentNode = data.children;
|
currentNode.value = data.children;
|
||||||
};
|
};
|
||||||
const remove = (node, data) => {
|
const remove = (node, data) => {
|
||||||
this.activeData.__config__.defaultValue = []; // 避免删除时报错
|
activeData.value.__config__.defaultValue = []; // 避免删除时报错
|
||||||
const { parent } = node;
|
const { parent } = node;
|
||||||
const children = parent.data.children || parent.data;
|
const children = parent.data.children || parent.data;
|
||||||
const index = children.findIndex((d) => d.id === data.id);
|
const index = children.findIndex((d) => d.id === data.id);
|
||||||
children.splice(index, 1);
|
children.splice(index, 1);
|
||||||
};
|
};
|
||||||
const addNode = (data) => {
|
const addNode = (data) => {
|
||||||
this.currentNode.push(data);
|
currentNode.value.push(data);
|
||||||
};
|
};
|
||||||
const setOptionValue = (item, val) => {
|
const setOptionValue = (item, val) => {
|
||||||
item.value = isNumberStr(val) ? +val : val;
|
item.value = isNumberStr(val) ? +val : val;
|
||||||
@ -1128,80 +1145,69 @@ const setDefaultValue = (val) => {
|
|||||||
if (Array.isArray(val)) {
|
if (Array.isArray(val)) {
|
||||||
return val.join(",");
|
return val.join(",");
|
||||||
}
|
}
|
||||||
// if (['string', 'number'].indexOf(typeof val) > -1) {
|
|
||||||
// return val
|
|
||||||
// }
|
|
||||||
if (typeof val === "boolean") {
|
if (typeof val === "boolean") {
|
||||||
return `${val}`;
|
return `${val}`;
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
const onDefaultValueInput = (str) => {
|
const onDefaultValueInput = (str) => {
|
||||||
if (Array.isArray(this.activeData.__config__.defaultValue)) {
|
if (Array.isArray(activeData.value.__config__.defaultValue)) {
|
||||||
// 数组
|
// 数组
|
||||||
this.$set(
|
activeData.value.__config__.defaultValue = str
|
||||||
this.activeData.__config__,
|
.split(",")
|
||||||
"defaultValue",
|
.map((val) => (isNumberStr(val) ? +val : val));
|
||||||
str.split(",").map((val) => (isNumberStr(val) ? +val : val))
|
|
||||||
);
|
|
||||||
} else if (["true", "false"].indexOf(str) > -1) {
|
} else if (["true", "false"].indexOf(str) > -1) {
|
||||||
// 布尔
|
// 布尔
|
||||||
this.$set(this.activeData.__config__, "defaultValue", JSON.parse(str));
|
activeData.value.__config__.defaultValue = JSON.parse(str);
|
||||||
} else {
|
} else {
|
||||||
// 字符串和数字
|
// 字符串和数字
|
||||||
this.$set(
|
activeData.value.__config__.defaultValue = isNumberStr(str) ? +str : str;
|
||||||
this.activeData.__config__,
|
|
||||||
"defaultValue",
|
|
||||||
isNumberStr(str) ? +str : str
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const onSwitchValueInput = (val, name) => {
|
const onSwitchValueInput = (val, name) => {
|
||||||
if (["true", "false"].indexOf(val) > -1) {
|
if (["true", "false"].indexOf(val) > -1) {
|
||||||
this.$set(this.activeData, name, JSON.parse(val));
|
activeData.value.name = JSON.parse(val);
|
||||||
} else {
|
} else {
|
||||||
this.$set(this.activeData, name, isNumberStr(val) ? +val : val);
|
activeData.value.name = isNumberStr(val) ? +val : val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const setTimeValue = (val, type) => {
|
const setTimeValue = (val, type) => {
|
||||||
const valueFormat = type === "week" ? dateTimeFormat.date : val;
|
const valueFormat = type === "week" ? dateTimeFormat.date : val;
|
||||||
this.$set(this.activeData.__config__, "defaultValue", null);
|
activeData.value.__config__.defaultValue = null;
|
||||||
this.$set(this.activeData, "value-format", valueFormat);
|
activeData.value.__config__["value-format"] = valueFormat;
|
||||||
this.$set(this.activeData, "format", val);
|
activeData.value.format = val;
|
||||||
};
|
};
|
||||||
const spanChange = (val) => {
|
const spanChange = (val) => {
|
||||||
formConf.value.span = val;
|
formConf.value.span = val;
|
||||||
};
|
};
|
||||||
const multipleChange = (val) => {
|
const multipleChange = (val) => {
|
||||||
this.$set(this.activeData.__config__, "defaultValue", val ? [] : "");
|
activeData.value.__config__.defaultValue = val ? [] : "";
|
||||||
};
|
};
|
||||||
const dateTypeChange = (val) => {
|
const dateTypeChange = (val) => {
|
||||||
this.setTimeValue(dateTimeFormat[val], val);
|
setTimeValue(dateTimeFormat[val], val);
|
||||||
};
|
};
|
||||||
const rangeChange = (val) => {
|
const rangeChange = (val) => {
|
||||||
this.$set(
|
activeData.value.__config__.defaultValue = val
|
||||||
this.activeData.__config__,
|
? [activeData.value.min, activeData.value.max]
|
||||||
"defaultValue",
|
: activeData.value.min;
|
||||||
val ? [this.activeData.min, this.activeData.max] : this.activeData.min
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
const rateTextChange = (val) => {
|
const rateTextChange = (val) => {
|
||||||
if (val) this.activeData["show-score"] = false;
|
if (val) activeData.value["show-score"] = false;
|
||||||
};
|
};
|
||||||
const rateScoreChange = (val) => {
|
const rateScoreChange = (val) => {
|
||||||
if (val) this.activeData["show-text"] = false;
|
if (val) activeData.value["show-text"] = false;
|
||||||
};
|
};
|
||||||
const colorFormatChange = (val) => {
|
const colorFormatChange = (val) => {
|
||||||
this.activeData.__config__.defaultValue = null;
|
activeData.value.__config__.defaultValue = null;
|
||||||
this.activeData["show-alpha"] = val.indexOf("a") > -1;
|
activeData.value["show-alpha"] = val.indexOf("a") > -1;
|
||||||
this.activeData.__config__.renderKey = +new Date(); // 更新renderKey,重新渲染该组件
|
activeData.value.__config__.renderKey = +new Date(); // 更新renderKey,重新渲染该组件
|
||||||
};
|
};
|
||||||
const openIconsDialog = (model) => {
|
const openIconsDialog = (model) => {
|
||||||
this.iconsVisible = true;
|
iconsVisible.value = true;
|
||||||
this.currentIconModel = model;
|
currentIconModel.value = model;
|
||||||
};
|
};
|
||||||
const setIcon = (val) => {
|
const setIcon = (val) => {
|
||||||
this.activeData[this.currentIconModel] = val;
|
activeData.value[currentIconModel.value] = val;
|
||||||
};
|
};
|
||||||
const tagChange = (tagIcon) => {
|
const tagChange = (tagIcon) => {
|
||||||
let target = inputComponents.find(
|
let target = inputComponents.find(
|
||||||
@ -1214,8 +1220,8 @@ const tagChange = (tagIcon) => {
|
|||||||
emit("tag-change", target);
|
emit("tag-change", target);
|
||||||
};
|
};
|
||||||
const changeRenderKey = () => {
|
const changeRenderKey = () => {
|
||||||
if (needRerenderList.includes(this.activeData.__config__.tag)) {
|
if (needRerenderList.includes(activeData.value.__config__.tag)) {
|
||||||
this.activeData.__config__.renderKey = +new Date();
|
activeData.value.__config__.renderKey = +new Date();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1302,7 +1308,6 @@ const justifyOptions = ref([
|
|||||||
const data = reactive({
|
const data = reactive({
|
||||||
layoutTreeProps: {
|
layoutTreeProps: {
|
||||||
label(data, node) {
|
label(data, node) {
|
||||||
console.log(data);
|
|
||||||
const config = data.__config__;
|
const config = data.__config__;
|
||||||
return data.componentName || `${config.label}: ${data.__vModel__}`;
|
return data.componentName || `${config.label}: ${data.__vModel__}`;
|
||||||
},
|
},
|
||||||
|
@ -7,13 +7,12 @@
|
|||||||
@open="onOpen"
|
@open="onOpen"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
>
|
>
|
||||||
<!-- v-on="$listeners" -->
|
|
||||||
<el-row :gutter="0">
|
<el-row :gutter="0">
|
||||||
<el-form
|
<el-form
|
||||||
ref="elForm"
|
ref="elFormRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
size="small"
|
size="default"
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
>
|
>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@ -61,7 +60,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { isNumberStr } from "@/utils/index";
|
import { isNumberStr } from "@/utils/index";
|
||||||
import { reactive, ref, toRefs, watch } from "vue";
|
import { reactive, ref, toRefs, watch } from "vue";
|
||||||
const emit = defineEmits(["update:visible", "commit"]);
|
const emit = defineEmits(["update:modelValue", "commit"]);
|
||||||
|
// const props = defineProps(["modelValue"]);
|
||||||
const id = ref(100);
|
const id = ref(100);
|
||||||
const dataType = ref("string");
|
const dataType = ref("string");
|
||||||
let inheritAttrs = false;
|
let inheritAttrs = false;
|
||||||
@ -106,11 +106,14 @@ const onOpen = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
const onClose = () => {};
|
const onClose = () => {};
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
emit("update:visible", false);
|
emit("update:modelValue", false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const elFormRef = ref();
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
this.$refs.elForm.validate((valid) => {
|
elFormRef.value.validate((valid) => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
if (dataType.value === "number") {
|
if (dataType.value === "number") {
|
||||||
formData.value.value = parseFloat(formData.value.value);
|
formData.value.value = parseFloat(formData.value.value);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
:clone="cloneComponent"
|
:clone="cloneComponent"
|
||||||
item-key="id"
|
item-key="id"
|
||||||
:sort="false"
|
:sort="false"
|
||||||
|
@end="onEnd"
|
||||||
>
|
>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div class="components-item" @click="addComponent(element)">
|
<div class="components-item" @click="addComponent(element)">
|
||||||
@ -119,30 +120,27 @@
|
|||||||
@tag-change="tagChange"
|
@tag-change="tagChange"
|
||||||
@fetch-data="fetchData"
|
@fetch-data="fetchData"
|
||||||
/>
|
/>
|
||||||
<!-- <el-input v-model="formConf.size"></el-input> -->
|
|
||||||
<!--
|
|
||||||
<form-drawer
|
<form-drawer
|
||||||
:visible.sync="drawerVisible"
|
v-model="drawerVisible"
|
||||||
:form-data="formData"
|
:form-data="formData"
|
||||||
size="100%"
|
size="100%"
|
||||||
:generate-conf="generateConf"
|
:generate-conf="generateConf"
|
||||||
/>
|
/>
|
||||||
-->
|
|
||||||
<json-drawer
|
<json-drawer
|
||||||
size="60%"
|
size="60%"
|
||||||
v-model="jsonDrawerVisible"
|
v-model="jsonDrawerVisible"
|
||||||
:json-str="JSON.stringify(formData)"
|
:json-str="JSON.stringify(formData)"
|
||||||
@refresh="refreshJson"
|
@refresh="refreshJson"
|
||||||
/>
|
/>
|
||||||
<!--
|
|
||||||
<code-type-dialog
|
<code-type-dialog
|
||||||
:visible.sync="dialogVisible"
|
v-model="dialogVisible"
|
||||||
title="选择生成类型"
|
title="选择生成类型"
|
||||||
:show-file-name="showFileName"
|
:show-file-name="showFileName"
|
||||||
@confirm="generate"
|
@confirm="generate"
|
||||||
/>
|
/>
|
||||||
<input id="copyNode" type="hidden" />
|
<input id="copyNode" type="hidden" />
|
||||||
-->
|
|
||||||
<!-- 表单配置详情 -->
|
<!-- 表单配置详情 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="formTitle"
|
:title="formTitle"
|
||||||
@ -168,21 +166,33 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { debounce } from "throttle-debounce";
|
import { debounce } from "throttle-debounce";
|
||||||
// import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import draggable from "vuedraggable";
|
import draggable from "vuedraggable";
|
||||||
|
import CodeTypeDialog from "./CodeTypeDialog.vue";
|
||||||
import logo from "@/assets/logo/logo.png";
|
import logo from "@/assets/logo/logo.png";
|
||||||
import { beautifierConf, titleCase, deepClone } from "@/utils/index";
|
import { beautifierConf, titleCase, deepClone } from "@/utils/index";
|
||||||
import drawingDefault from "@/utils/generator/drawingDefault";
|
import drawingDefault from "@/utils/generator/drawingDefault";
|
||||||
import draggableItem from "./DraggableItem";
|
import draggableItem from "./DraggableItem";
|
||||||
import RightPanel from "./RightPanel.vue";
|
import RightPanel from "./RightPanel.vue";
|
||||||
|
import loadBeautifier from "@/utils/loadBeautifier";
|
||||||
import JsonDrawer from "./JsonDrawer";
|
import JsonDrawer from "./JsonDrawer";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import FormDrawer from "./FormDrawer.vue";
|
||||||
|
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
|
||||||
|
import $download from "@/plugins/download.js";
|
||||||
import {
|
import {
|
||||||
inputComponents,
|
inputComponents,
|
||||||
selectComponents,
|
selectComponents,
|
||||||
layoutComponents,
|
layoutComponents,
|
||||||
formConf as formConfig,
|
formConf as formConfig,
|
||||||
} from "@/utils/generator/config";
|
} from "@/utils/generator/config";
|
||||||
|
import {
|
||||||
|
makeUpHtml,
|
||||||
|
vueTemplate,
|
||||||
|
vueScript,
|
||||||
|
cssStyle,
|
||||||
|
} from "@/utils/generator/html";
|
||||||
|
import { makeUpJs } from "@/utils/generator/js";
|
||||||
|
import { makeUpCss } from "@/utils/generator/css";
|
||||||
import {
|
import {
|
||||||
getDrawingList,
|
getDrawingList,
|
||||||
saveDrawingList,
|
saveDrawingList,
|
||||||
@ -192,8 +202,11 @@ import {
|
|||||||
} from "@/utils/db";
|
} from "@/utils/db";
|
||||||
import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
|
import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
let tempActiveData;
|
let tempActiveData;
|
||||||
let oldActiveId;
|
let oldActiveId;
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
const drawingListInDB = getDrawingList();
|
const drawingListInDB = getDrawingList();
|
||||||
const formConfInDB = getFormConf();
|
const formConfInDB = getFormConf();
|
||||||
const idGlobal = ref(getIdGlobal());
|
const idGlobal = ref(getIdGlobal());
|
||||||
@ -218,6 +231,7 @@ const jsonDrawerVisible = ref(false);
|
|||||||
const generateConf = ref(null);
|
const generateConf = ref(null);
|
||||||
const showFileName = ref(false);
|
const showFileName = ref(false);
|
||||||
const drawingList = ref([]);
|
const drawingList = ref([]);
|
||||||
|
const operationType = ref(null);
|
||||||
const activeData = ref(drawingDefault[0]);
|
const activeData = ref(drawingDefault[0]);
|
||||||
const activeId = ref(drawingDefault[0].formId);
|
const activeId = ref(drawingDefault[0].formId);
|
||||||
const formOpen = ref(false);
|
const formOpen = ref(false);
|
||||||
@ -228,7 +242,7 @@ const data = reactive({
|
|||||||
// 表单参数
|
// 表单参数
|
||||||
formObj: {
|
formObj: {
|
||||||
formId: undefined,
|
formId: undefined,
|
||||||
formName: "332",
|
formName: undefined,
|
||||||
content: undefined,
|
content: undefined,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
},
|
},
|
||||||
@ -274,10 +288,10 @@ const setRespData = (component, resp) => {
|
|||||||
// 此时赋值代码可写成 component[dataConsumer] = respData;
|
// 此时赋值代码可写成 component[dataConsumer] = respData;
|
||||||
// 但为支持更深层级的赋值(如:dataConsumer的值为'options.data'),使用setObjectValueReduce
|
// 但为支持更深层级的赋值(如:dataConsumer的值为'options.data'),使用setObjectValueReduce
|
||||||
setObjectValueReduce(component, dataConsumer, respData);
|
setObjectValueReduce(component, dataConsumer, respData);
|
||||||
const i = drawingList.findIndex(
|
const i = drawingList.value.findIndex(
|
||||||
(item) => item.__config__.renderKey === renderKey
|
(item) => item.__config__.renderKey === renderKey
|
||||||
);
|
);
|
||||||
if (i > -1) this.$set(drawingList, i, component);
|
if (i > -1) drawingList.value[i] = component;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchData = (component) => {
|
const fetchData = (component) => {
|
||||||
@ -308,7 +322,6 @@ const cloneComponent = (origin) => {
|
|||||||
const clone = deepClone(origin);
|
const clone = deepClone(origin);
|
||||||
const config = clone.__config__;
|
const config = clone.__config__;
|
||||||
config.span = formConf.value.span; // 生成代码时,会根据span做精简判断
|
config.span = formConf.value.span; // 生成代码时,会根据span做精简判断
|
||||||
console.log(formConf.value);
|
|
||||||
createIdAndKey(clone);
|
createIdAndKey(clone);
|
||||||
clone.placeholder !== undefined && (clone.placeholder += config.label);
|
clone.placeholder !== undefined && (clone.placeholder += config.label);
|
||||||
tempActiveData = clone;
|
tempActiveData = clone;
|
||||||
@ -339,20 +352,20 @@ const showJson = () => {
|
|||||||
jsonDrawerVisible.value = true;
|
jsonDrawerVisible.value = true;
|
||||||
};
|
};
|
||||||
const download = () => {
|
const download = () => {
|
||||||
this.dialogVisible = true;
|
dialogVisible.value = true;
|
||||||
this.showFileName = true;
|
showFileName.value = true;
|
||||||
this.operationType = "download";
|
operationType.value = "download";
|
||||||
};
|
};
|
||||||
const run = () => {
|
const run = () => {
|
||||||
// TODO 弹窗类型异常
|
// TODO 弹窗类型异常
|
||||||
// this.dialogVisible = true
|
// this.dialogVisible = true
|
||||||
// this.showFileName = false
|
// this.showFileName = false
|
||||||
this.operationType = "run";
|
operationType.value = "run";
|
||||||
let data = {
|
let data = {
|
||||||
fileName: undefined,
|
fileName: undefined,
|
||||||
type: "file",
|
type: "file",
|
||||||
};
|
};
|
||||||
this.generate(data);
|
generate(data);
|
||||||
};
|
};
|
||||||
const saveIdGlobalDebounce = debounce(340, saveIdGlobal);
|
const saveIdGlobalDebounce = debounce(340, saveIdGlobal);
|
||||||
const saveDrawingListDebounce = debounce(340, saveDrawingList);
|
const saveDrawingListDebounce = debounce(340, saveDrawingList);
|
||||||
@ -389,18 +402,18 @@ const AssembleFormData = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
const generate = (data) => {
|
const generate = (data) => {
|
||||||
const func = this[`exec${titleCase(this.operationType)}`];
|
const func = `exec${titleCase(operationType.value)}`;
|
||||||
this.generateConf = data;
|
generateConf.value = data;
|
||||||
func && func(data);
|
func && eval(`${func}(data)`);
|
||||||
};
|
};
|
||||||
const execRun = (data) => {
|
const execRun = (data) => {
|
||||||
this.AssembleFormData();
|
AssembleFormData();
|
||||||
this.drawerVisible = true;
|
drawerVisible.value = true;
|
||||||
};
|
};
|
||||||
const execDownload = (data) => {
|
const execDownload = (data) => {
|
||||||
const codeStr = this.generateCode();
|
const codeStr = generateCode();
|
||||||
const blob = new Blob([codeStr], { type: "text/plain;charset=utf-8" });
|
const blob = new Blob([codeStr], { type: "text/plain;charset=utf-8" });
|
||||||
this.$download.saveAs(blob, data.fileName);
|
$download.saveAs(blob, data.fileName);
|
||||||
};
|
};
|
||||||
const execCopy = (data) => {
|
const execCopy = (data) => {
|
||||||
document.getElementById("copyNode").click();
|
document.getElementById("copyNode").click();
|
||||||
@ -424,17 +437,25 @@ const drawingItemDelete = (index, list) => {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const len = drawingList.value.length;
|
const len = drawingList.value.length;
|
||||||
if (len) {
|
if (len) {
|
||||||
activeFormItem(this.drawingList[len - 1]);
|
activeFormItem(drawingList.value[len - 1]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const generateCode = () => {
|
const generateCode = () => {
|
||||||
const { type } = this.generateConf;
|
const { type } = generateConf.value;
|
||||||
AssembleFormData();
|
AssembleFormData();
|
||||||
const script = vueScript(makeUpJs(this.formData, type));
|
const extraScript = vueScript(`
|
||||||
const html = vueTemplate(makeUpHtml(this.formData, type));
|
export default {
|
||||||
const css = cssStyle(makeUpCss(this.formData));
|
inheritAttrs: false
|
||||||
return beautifier.html(html + script + css, beautifierConf.html);
|
}
|
||||||
|
`);
|
||||||
|
const script = vueScript(makeUpJs(formData.value, type), true);
|
||||||
|
const html = vueTemplate(makeUpHtml(formData.value, type));
|
||||||
|
const css = cssStyle(makeUpCss(formData.value));
|
||||||
|
return beautifier.html(
|
||||||
|
html + extraScript + script + css,
|
||||||
|
beautifierConf.html
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const copy = () => {
|
const copy = () => {
|
||||||
@ -443,57 +464,59 @@ const copy = () => {
|
|||||||
operationType.value = "copy";
|
operationType.value = "copy";
|
||||||
};
|
};
|
||||||
const tagChange = (newTag) => {
|
const tagChange = (newTag) => {
|
||||||
newTag = this.cloneComponent(newTag);
|
newTag = cloneComponent(newTag);
|
||||||
const config = newTag.__config__;
|
const config = newTag.__config__;
|
||||||
newTag.__vModel__ = this.activeData.__vModel__;
|
newTag.__vModel__ = activeData.value.__vModel__;
|
||||||
config.formId = this.activeId;
|
config.formId = activeId.value;
|
||||||
config.span = this.activeData.__config__.span;
|
config.span = activeData.value.__config__.span;
|
||||||
this.activeData.__config__.tag = config.tag;
|
activeData.value.__config__.tag = config.tag;
|
||||||
this.activeData.__config__.tagIcon = config.tagIcon;
|
activeData.value.__config__.tagIcon = config.tagIcon;
|
||||||
this.activeData.__config__.document = config.document;
|
activeData.value.__config__.document = config.document;
|
||||||
if (
|
if (
|
||||||
typeof this.activeData.__config__.defaultValue ===
|
typeof activeData.value.__config__.defaultValue ===
|
||||||
typeof config.defaultValue
|
typeof config.defaultValue
|
||||||
) {
|
) {
|
||||||
config.defaultValue = this.activeData.__config__.defaultValue;
|
config.defaultValue = activeData.value.__config__.defaultValue;
|
||||||
}
|
}
|
||||||
Object.keys(newTag).forEach((key) => {
|
Object.keys(newTag).forEach((key) => {
|
||||||
if (this.activeData[key] !== undefined) {
|
if (activeData.value[key] !== undefined) {
|
||||||
newTag[key] = this.activeData[key];
|
newTag[key] = activeData.value[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.activeData = newTag;
|
activeData.value = newTag;
|
||||||
this.updateDrawingList(newTag, this.drawingList);
|
updateDrawingList(newTag, drawingList.value);
|
||||||
};
|
};
|
||||||
const updateDrawingList = (newTag, list) => {
|
const updateDrawingList = (newTag, list) => {
|
||||||
const index = list.findIndex(
|
const index = list.findIndex(
|
||||||
(item) => item.__config__.formId === this.activeId
|
(item) => item.__config__.formId === activeId.value
|
||||||
);
|
);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
list.splice(index, 1, newTag);
|
list.splice(index, 1, newTag);
|
||||||
} else {
|
} else {
|
||||||
list.forEach((item) => {
|
list.forEach((item) => {
|
||||||
if (Array.isArray(item.__config__.children))
|
if (Array.isArray(item.__config__.children))
|
||||||
this.updateDrawingList(newTag, item.__config__.children);
|
updateDrawingList(newTag, item.__config__.children);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const refreshJson = (data) => {
|
const refreshJson = (data) => {
|
||||||
drawingList.value = deepClone(data.fields);
|
drawingList.value = deepClone(data.fields);
|
||||||
delete data.fields;
|
delete data.fields;
|
||||||
this.formConf = data;
|
formConf.value = data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 保存表单信息 */
|
/** 保存表单信息 */
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
formRef.value.validate((valid) => {
|
formRef.value.validate((valid) => {
|
||||||
|
console.log(formObj.value);
|
||||||
|
return;
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (this.form.formId != null) {
|
if (formObj.value.formId != null) {
|
||||||
updateForm(this.form).then((response) => {
|
updateForm(formObj.value).then((response) => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addForm(this.form).then((response) => {
|
addForm(formObj.value).then((response) => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -517,36 +540,36 @@ onMounted(() => {
|
|||||||
activeFormItem(drawingList.value[0]);
|
activeFormItem(drawingList.value[0]);
|
||||||
|
|
||||||
drawingList.value = [];
|
drawingList.value = [];
|
||||||
// const formId = that.$route.query && that.$route.query.formId;
|
const formId = route.query && route.query.formId;
|
||||||
// if (formId) {
|
if (formId) {
|
||||||
// getForm(formId).then((res) => {
|
getForm(formId).then((res) => {
|
||||||
// that.formConf = JSON.parse(res.data.content);
|
formConf.value = JSON.parse(res.data.content);
|
||||||
// that.drawingList = that.formConf.fields;
|
drawingList.value = formConf.value.fields;
|
||||||
// that.form = res.data;
|
formObj.value = res.data;
|
||||||
// });
|
});
|
||||||
// } else {
|
} else {
|
||||||
// if (formConfInDB) {
|
if (formConfInDB) {
|
||||||
// that.formConf = formConfInDB;
|
formConf.value = formConfInDB;
|
||||||
// that.formConf.fields = null;
|
formConf.value.fields = null;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// loadBeautifier((btf) => {
|
loadBeautifier((btf) => {
|
||||||
// beautifier = btf;
|
beautifier = btf;
|
||||||
// });
|
});
|
||||||
// const clipboard = new ClipboardJS("#copyNode", {
|
const clipboard = new ClipboardJS("#copyNode", {
|
||||||
// text: (trigger) => {
|
text: (trigger) => {
|
||||||
// const codeStr = this.generateCode();
|
const codeStr = generateCode();
|
||||||
// this.$notify({
|
ElNotification({
|
||||||
// title: "成功",
|
title: "成功",
|
||||||
// message: "代码已复制到剪切板,可粘贴。",
|
message: "代码已复制到剪切板,可粘贴。",
|
||||||
// type: "success",
|
type: "success",
|
||||||
// });
|
});
|
||||||
// return codeStr;
|
return codeStr;
|
||||||
// },
|
},
|
||||||
// });
|
});
|
||||||
// clipboard.on("error", (e) => {
|
clipboard.on("error", (e) => {
|
||||||
// this.$message.error("代码复制失败");
|
ElMessage.error("代码复制失败");
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -574,7 +597,6 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
drawingList,
|
drawingList,
|
||||||
(val) => {
|
(val) => {
|
||||||
// console.log(val);
|
|
||||||
saveDrawingListDebounce(val);
|
saveDrawingListDebounce(val);
|
||||||
if (val.length === 0) idGlobal.value = 100;
|
if (val.length === 0) idGlobal.value = 100;
|
||||||
},
|
},
|
||||||
@ -587,120 +609,13 @@ watch(
|
|||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- <script>
|
// 防止 firefox 下 拖拽 会新打卡一个选项卡
|
||||||
import { debounce } from "throttle-debounce";
|
document.body.ondrop = (event) => {
|
||||||
import ClipboardJS from "clipboard";
|
event.preventDefault();
|
||||||
import render from "@/utils/generator/render";
|
event.stopPropagation();
|
||||||
import FormDrawer from "./FormDrawer";
|
|
||||||
|
|
||||||
|
|
||||||
import {
|
|
||||||
inputComponents,
|
|
||||||
selectComponents,
|
|
||||||
layoutComponents,
|
|
||||||
formConf,
|
|
||||||
} from "@/utils/generator/config";
|
|
||||||
import { beautifierConf, titleCase, deepClone } 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 CodeTypeDialog from "./CodeTypeDialog";
|
|
||||||
import DraggableItem from "./DraggableItem";
|
|
||||||
|
|
||||||
import loadBeautifier from "@/utils/loadBeautifier";
|
|
||||||
import { getForm, addForm, updateForm } from "@/api/workflow/form";
|
|
||||||
import axios from "axios";
|
|
||||||
import Vue from "vue";
|
|
||||||
|
|
||||||
let beautifier;
|
|
||||||
const emptyActiveData = { style: {}, autosize: {} };
|
|
||||||
let oldActiveId;
|
|
||||||
|
|
||||||
const drawingListInDB = getDrawingList();
|
|
||||||
const formConfInDB = getFormConf();
|
|
||||||
|
|
||||||
Vue.prototype.$axios = axios;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
draggable,
|
|
||||||
render,
|
|
||||||
FormDrawer,
|
|
||||||
JsonDrawer,
|
|
||||||
RightPanel,
|
|
||||||
CodeTypeDialog,
|
|
||||||
DraggableItem,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
logo,
|
|
||||||
idGlobal,
|
|
||||||
formConf,
|
|
||||||
inputComponents,
|
|
||||||
selectComponents,
|
|
||||||
layoutComponents,
|
|
||||||
labelWidth: 100,
|
|
||||||
|
|
||||||
drawingData: {},
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
saveDrawingListDebounce: debounce(340, saveDrawingList),
|
|
||||||
saveIdGlobalDebounce: debounce(340, saveIdGlobal),
|
|
||||||
leftComponents: [
|
|
||||||
{
|
|
||||||
title: "输入型组件",
|
|
||||||
list: inputComponents,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "选择型组件",
|
|
||||||
list: selectComponents,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "布局型组件",
|
|
||||||
list: layoutComponents,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 防止 firefox 下 拖拽 会新打卡一个选项卡
|
|
||||||
document.body.ondrop = (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script> -->
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
body,
|
body,
|
||||||
|
@ -11,6 +11,7 @@ export default function createVitePlugins(viteEnv, isBuild = false) {
|
|||||||
vue(),
|
vue(),
|
||||||
vueJsx({
|
vueJsx({
|
||||||
transformOn: true,
|
transformOn: true,
|
||||||
|
// include: ["src/**/*.vue", "src/**/*.jsx"],
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
vitePlugins.push(createAutoImport());
|
vitePlugins.push(createAutoImport());
|
||||||
|
Reference in New Issue
Block a user