sgCreateReadonlyForm源码
<template>
<!--
前往https://blog.csdn.net/qq_37860634/article/details/141389231
查看使用说明
-->
<div :class="$options.name">
<div class="sg-head">
只读表单生成工具<el-dropdown
:show-timeout="0"
:split-button="false"
:placement="`bottom`"
@command="$router.push(`/demo?id=${$event}`).catch(() => true)"
>
<el-button
style="margin-left: 10px"
type="primary"
size="mini"
icon="el-icon-more"
plain
title="更多"
circle
/>
<el-dropdown-menu
slot="dropdown"
style="transition: none; overflow-y: auto; max-height: 400px; margin-top: 5px"
>
<el-dropdown-item
:command="item.command"
v-for="(item, index) in dropdownItems"
:key="index"
:divided="item.divided"
v-if="
item.hasOwnProperty('hide')
? typeof item.hide === 'function'
? !item.hide(item)
: !item.hide
: true
"
:active="item.command == dropdownActive"
:disabled="item.command == dropdownActive"
>
<template>
<i :class="item.icon" v-if="item.icon" />{{ item.label }}</template
>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="sg-container">
<div class="sg-start">
<div style="margin-bottom: 10px">字段中文名</div>
<div style="display: flex; margin-bottom: 10px">
<el-select
style="width: 150px"
v-model="selectValue_type"
@change="(d) => {}"
:placeholder="`请选择数据内容类型`"
>
<el-option
v-for="(select, index) in selectOptions_type"
:key="index"
:value="select.value"
:label="select.label"
:disabled="select.disabled"
></el-option>
</el-select>
<template v-if="selectValue_type == 2">
<div style="display: flex; align-items: center; margin-left: 10px">
<label style="margin-right: 5px">fieldName</label>
<el-input
style="width: 150px"
ref="fieldName"
v-model.trim="fieldNameValue"
maxlength="20"
:show-word-limit="false"
:placeholder="`字段名`"
@focus="$refs.fieldName.select()"
clearable
/>
<label style="margin-left: 10px; margin-right: 5px">keyName</label>
<el-input
style="width: 150px"
ref="keyName"
v-model.trim="keyNameValue"
maxlength="20"
:show-word-limit="false"
:placeholder="`字段值名`"
@focus="$refs.keyName.select()"
clearable
/>
</div>
</template>
</div>
<el-input
ref="textareaValue1"
style="margin-bottom: 10px"
type="textarea"
:placeholder="
this.selectOptions_type.find((v) => v.value == this.selectValue_type)
.placeholder
"
v-model.trim="textareaValue1"
show-word-limit
/>
<el-button type="primary" @click="createResult">生成表格数据</el-button>
</div>
<div class="sg-center">→</div>
<div class="sg-end">
<div style="margin-bottom: 10px">生成结果</div>
<el-input
style="margin-bottom: 10px"
type="textarea"
:placeholder="`请复制结果`"
v-model.trim="textareaValue2"
show-word-limit
/>
<el-button type="primary" @click="copyResult">复制</el-button>
</div>
</div>
</div>
</template>
<script>
import pinyin from "@/js/pinyin";
export default {
name: "sgCreateReadonlyForm",
data() {
return {
dropdownActive: this.$route.query.id,
dropdownItems: [
{ label: "接口代码生成工具", command: "demoCreateAPI" },
{ label: "接口方法生成工具", command: "demoCreateAPIFunction" },
{ label: "表格列生成工具", command: "demoCreateTableColumn" },
{ label: "表格数据生成工具", command: "demoCreateTableData" },
{ label: "表单生成工具", command: "demoCreateForm" },
{ label: "只读表单生成工具", command: "demoCreateReadonlyForm" },
{ label: "拼音生成工具", command: "demoCreatePinyin" },
],
selectOptions_type: [
{
value: 1,
label: "文本",
placeholder: `请粘贴字段中文名(或者:字段英文名+空格+字段中文名)`,
},
{ value: 2, label: "json数据", placeholder: `请粘贴键值对描述json数组` },
],
selectValue_type: 1,
fieldNameValue: `fieldName`,
keyNameValue: `fieldName_TEXT`,
textareaValue1: "",
textareaValue2: "",
};
},
watch: {
textareaValue1(newValue, oldValue) {
newValue && this.createResult(newValue);
},
},
methods: {
createResult(d) {
let formFieldData = {}; //表单的字段对象(描述字段名的键值对)
switch (this.selectValue_type) {
case 1:
let texts = this.textareaValue1
.split("\n")
.map((v) => v.split("\t").join("").trim());
texts = texts.filter((v, i, ar) => v !== ``);
texts.map((v) => {
let strings = v.replace(/\s+/g, ` `).split(` `); //用空格分隔开两列字段名
let label = ``;
let prop = ``;
// 如果是多列内容
if (strings.length > 1) {
// 如果第一列的字符串是中文
if (this.$g.checkEverything(`cn`, strings[0])) {
label = strings[0];
prop = strings[1];
} else {
label = strings[1];
prop = strings[0];
}
} else {
// 如果是单列内容
prop = pinyin.getCamelChars(v);
label = v;
}
formFieldData[prop] = label;
});
break;
case 2:
if (this.fieldNameValue && this.keyNameValue) {
} else {
return this.$message.error(`fieldName和keyName都要填写`);
}
if (this.$g.json.isJSON(this.textareaValue1)) {
let arr = JSON.parse(this.textareaValue1);
arr.map((v) => {
let prop = v[this.fieldNameValue];
let label = v[this.keyNameValue];
formFieldData[prop] = label;
});
} else {
return this.$message.error(`请输入正确的json格式的对象数组内容`);
}
break;
}
this.textareaValue2 = this.createFormHTML(formFieldData);
this.copyResult(); //自动复制生成结果
},
createFormHTML(formFieldData) {
let r = ``;
Object.keys(formFieldData || {}).forEach((k) => {
let itemData = { key: k.replace(/[^a-zA-Z]/g, ""), value: formFieldData[k] };
r += `${this.createFormItemHTML(itemData)}\n`;
});
return `<el-form @submit.native.prevent label-position="right" size="mini" >\n${r}</el-form>`;
},
createFormItemHTML(itemData) {
let formItem = `<el-form-item :label="\`${itemData.value}\`" label-width="80px">
<span>{{form.${itemData.key}}}</span>
</el-form-item>`;
return formItem;
},
copyResult(d) {
this.$g.copy(this.textareaValue2, true);
this.$nextTick(() => {
this.$refs.textareaValue1.select();
});
},
},
};
</script>
<style lang="scss" scoped>
.sgCreateReadonlyForm {
width: 100%;
height: 100%;
position: absolute;
box-sizing: border-box;
padding: 20px;
.sg-head {
display: flex;
align-items: center;
font-size: 24px;
font-weight: bold;
color: #409eff;
margin-bottom: 10px;
}
.sg-container {
display: flex;
flex-wrap: nowrap;
height: calc(100vh - 70px);
& > .sg-start {
width: calc(50% - 20px);
height: 100%;
flex-shrink: 0;
display: flex;
flex-direction: column;
}
& > .sg-center {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
margin: 0 10px;
font-size: 24px;
color: #409eff;
font-weight: bold;
}
& > .sg-end {
width: calc(50% - 20px);
height: 100%;
flex-shrink: 0;
display: flex;
flex-direction: column;
}
>>> .el-textarea {
width: 100%;
height: 100%;
textarea {
width: 100%;
height: 100%;
max-height: revert;
}
}
}
}
</style>