1
0
mirror of https://github.com/sahadev/vue-component-creater-ui.git synced 2025-06-08 14:34:05 +08:00

feat: 支持单文件二次编辑

This commit is contained in:
shangbin 2021-11-16 19:58:28 +08:00
parent 4cde9098bc
commit 2f4b143550
8 changed files with 139 additions and 19 deletions

View File

@ -1,14 +1,17 @@
<template> <template>
<vcc :initCodeEntity="codeStructure" @updateCodeEntity="onCodeUpdate"></vcc> <!-- <vcc :initCodeEntity="codeStructure" @updateCodeEntity="onCodeUpdate"></vcc> -->
<compile-vue-online></compile-vue-online>
</template> </template>
<script> <script>
import CompileVueOnline from './test/compileVueOnline.vue'
// VCC // VCC
const initCodeStr = '{"template":{"lc_id":"root","__children":[{"div":{"class":"container","style":"min-height: 100%; padding-bottom: 100px;","lc_id":"container","__text__":"Hello欢迎使用LCG请往此区域拖拽组件","__children":[{"el-button":{"lc-mark":"","type":"danger","lc_id":"COAAYXizyI","__children":[],"__text__":"危险按钮","@click":"onButtonClick","size":"small"}}]}}]}}' const initCodeStr = '{"template":{"lc_id":"root","__children":[{"div":{"class":"container","style":"min-height: 100%; padding-bottom: 100px;","lc_id":"container","__text__":"Hello欢迎使用LCG请往此区域拖拽组件","__children":[{"el-button":{"lc-mark":"","type":"danger","lc_id":"COAAYXizyI","__children":[],"__text__":"危险按钮","@click":"onButtonClick","size":"small"}}]}}]}}'
export default { export default {
components: { components: {
vcc: () => import('./components-v2/VCC.vue') vcc: () => import('./components-v2/VCC.vue'),
CompileVueOnline
}, },
data() { data() {
return { return {

View File

@ -24,7 +24,8 @@
<div class="copy"> <div class="copy">
<div style="display:inline-block; width:260px;"> <div style="display:inline-block; width:260px;">
<el-alert title="遇到问题请查阅页面左下角的帮助" type="info"></el-alert> <el-alert title="遇到问题?点击我查看帮助文档" @click="help" type="info">
</el-alert>
</div> </div>
<el-tooltip effect="dark" content="编辑JS逻辑" placement="top-start"> <el-tooltip effect="dark" content="编辑JS逻辑" placement="top-start">
@ -230,6 +231,10 @@ export default {
saveJSCode(code) { saveJSCode(code) {
this.mainPanelProvider.saveJSCode(code); this.mainPanelProvider.saveJSCode(code);
},
help() {
window.open('/doc')
} }
}, },
fillter: {}, fillter: {},

View File

@ -84,11 +84,16 @@ export default {
}, },
computed: { computed: {
prettyCode() { prettyCode() {
return prettier.format(this.rawCode, { try {
parser: "html", return prettier.format(this.rawCode, {
plugins: [parserHtml], parser: "html",
vueIndentScriptAndStyle: true, plugins: [parserHtml],
}); vueIndentScriptAndStyle: true,
});
} catch (error) {
return this.rawCode;
}
}, },
formatCode() { formatCode() {

View File

@ -47,10 +47,14 @@ export class MainPanelProvider {
const readyForMoutedElement = this.createMountedElement(); const readyForMoutedElement = this.createMountedElement();
// 生成原始代码 // 生成原始代码
const code = this.codeGenerator.outputVueCodeWithJsonObj(rawDataStructure); let code = this.codeGenerator.outputVueCodeWithJsonObj(rawDataStructure);
// 将xxx: () => {} 转换为xxx(){}
code = code.replace(/:\s*\(([\w\s]*)\)\s*=>/g,"\($1\)");
// 生成展示代码 // 生成展示代码
const codeForShow = code.replace(/\s{1}lc_id=".+"/g, ''); let codeForShow = code.replace(/\s{1}lc_id=".+"/g, '');
codeForShow = codeForShow.replace(/\s{1}lc-mark/g, "");
this.eventEmitter.emit("codeCreated", codeForShow); this.eventEmitter.emit("codeCreated", codeForShow);
console.groupEnd(); console.groupEnd();
@ -59,9 +63,6 @@ export class MainPanelProvider {
let newScript = script.content.replace(/\s*export default\s*/, "") let newScript = script.content.replace(/\s*export default\s*/, "")
// 将xxx: () => {} 转换为xxx(){}
newScript = newScript.replace(/:\s*\(([\w\s]*)\)\s*=>/g,"\($1\)");
const componentOptions = (new Function(`return ${newScript}`))(); const componentOptions = (new Function(`return ${newScript}`))();
const res = Vue.compile(template.content); const res = Vue.compile(template.content);
@ -249,7 +250,7 @@ export class MainPanelProvider {
this.eventEmitter.emit('onMerged'); this.eventEmitter.emit('onMerged');
}); });
this.render(window.tree.root); this.render(this._rawDataStructure);
} }
}); });
} }

View File

@ -1,4 +1,4 @@
const compiler = require("./compileComponent.js"); const { compiler } = require("./compileComponent.js");
const glob = require("glob"); const glob = require("glob");
const path = require("path"); const path = require("path");
@ -14,13 +14,13 @@ glob(
{ {
cwd: componentsPath, cwd: componentsPath,
absolute: true, absolute: true,
ignore: ['**/element/index.vue', '**/vant/index.vue', '**/iview/index.vue'] ignore: ["**/element/index.vue", "**/vant/index.vue", "**/iview/index.vue"],
}, },
function (er, files) { function (er, files) {
console.info(`正在对${files.length}个文件进行编译...`); console.info(`正在对${files.length}个文件进行编译...`);
files.forEach((filePath) => { files.forEach((filePath) => {
console.info(`正在编译${filePath}`); console.info(`正在编译${filePath}`);
compiler(filePath);
}); });
} }
); );

View File

@ -178,7 +178,7 @@ function findAObject(array, propertyName) {
return module ? module[propertyName] : null; return module ? module[propertyName] : null;
} }
module.exports = async function (path) { async function compiler(path) {
if (!_path.isAbsolute(path)) path = _path.join(process.cwd(), path); if (!_path.isAbsolute(path)) path = _path.join(process.cwd(), path);
if (fse.pathExistsSync(path)) { if (fse.pathExistsSync(path)) {
const xmlData = fs.readFileSync(path, { const xmlData = fs.readFileSync(path, {
@ -278,3 +278,8 @@ function outputToFile(sourceObject, path) {
fse.ensureFileSync(outputPath); fse.ensureFileSync(outputPath);
fs.writeFileSync(outputPath, `export default ${JSON.stringify(sourceObject)}`); fs.writeFileSync(outputPath, `export default ${JSON.stringify(sourceObject)}`);
} }
module.exports = {
compiler,
ergodic
}

View File

@ -0,0 +1,69 @@
<template>
<div class="container" style="min-height: 100%; padding-bottom: 100px;">
<div>
<el-input v-model="code" type="textarea" :rows="4" />
<el-button lc-mark @click="compile">解析</el-button>
</div>
<vcc :initCodeEntity="codeStructure" @updateCodeEntity="onCodeUpdate"></vcc>
</div>
</template>
<script>
import { html2Json } from '../libs/bundle-html2json-esm';
import vcc from '../components-v2/VCC.vue';
import { ergodic } from '../utils/common';
function findAObject(array, propertyName) {
const module = array.find(function (ele) {
return ele[propertyName];
});
return module || null;
}
export default {
props: [],
components: {
vcc,
},
data: () => {
return {
code: '',
codeStructure: ""
}
},
watch: {},
computed: {},
beforeCreate: () => { },
created: () => { },
beforeMount: () => { },
mounted: async () => {
},
beforeUpdate: () => { },
updated: () => { },
destoryed: () => { },
methods: {
async compile() {
const obj = await html2Json(this.code);
const template = findAObject(obj.root.__children, 'template');
ergodic(template);
this.codeStructure = template;
},
onCodeUpdate(newCodeEntity) {
//
}
},
fillter: {},
}
</script>
<style scoped>
.container {
}
</style>

View File

@ -1,4 +1,5 @@
import isEqual from "lodash/isEqual"; import isEqual from "lodash/isEqual";
import cryptoRandomString from "crypto-random-string";
export function getRawComponentKey(__rawVueInfo__) { export function getRawComponentKey(__rawVueInfo__) {
return Object.keys(__rawVueInfo__)[0]; return Object.keys(__rawVueInfo__)[0];
@ -22,3 +23,34 @@ export function isArray(arr) {
export function isObject(obj) { export function isObject(obj) {
return Object.prototype.toString.apply(obj) === "[object Object]"; return Object.prototype.toString.apply(obj) === "[object Object]";
} }
/**
* 遍历对象添加ID
* @param {*} jsonObj
*/
export function ergodic(jsonObj) {
if (jsonObj) {
for (const key in jsonObj) {
if (jsonObj.hasOwnProperty(key)) {
const element = jsonObj[key];
if (isArray(element)) {
element.forEach((item) => {
if (isObject(item)) {
ergodic(item);
delete item.lc_id;
}
});
} else if (isObject(element)) {
ergodic(element);
} else {
}
}
}
// 添加ID
if (!jsonObj["lc_id"]) {
jsonObj["lc_id"] = cryptoRandomString({ length: 10, type: "base64" });
}
}
}