Skip to content

Commit 5d6d7db

Browse files
author
shangbin
committed
Merge branch 'logicSaveAndInit' into vue3
2 parents 5a4ac16 + a9c2590 commit 5d6d7db

File tree

10 files changed

+130
-58
lines changed

10 files changed

+130
-58
lines changed

src/App.vue

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,44 @@
11
<template>
2-
<vcc :initCodeEntity="codeStructure" @updateCodeEntity="onCodeUpdate"></vcc>
2+
<vcc :initCodeEntity="codeInfoEntity" @updateCodeEntity="onCodeUpdate"></vcc>
33
</template>
44

55
<script>
66
import { defineAsyncComponent } from 'vue'
77
// 以这样一段结构初始化VCC组件
8-
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"}}]}}]}}'
8+
const initCodeStr = '{"template":{"lc_id":"root","__children":[{"div":{"class":"container","style":"min-height: 100%; padding-bottom: 100px;","lc_id":"container","__text__":"Hello,欢迎使用LCG,请往此区域拖拽组件","__children":[{"div": {"__text__": "{{showText}}", "lc_id": "text"}},{"el-button":{"lc-mark":"","type":"danger","lc_id":"COAAYXizyI","__children":[],"__text__":"{{showValue}}","@click":"hello","size":"small"}}]}}]}}'
99
1010
export default {
1111
components: {
1212
vcc: defineAsyncComponent(() => import('./components-v2/VCC.vue')),
1313
},
1414
data() {
1515
return {
16-
codeStructure: JSON.parse(initCodeStr),
16+
codeInfoEntity: {
17+
codeStructure: JSON.parse(initCodeStr),
18+
JSCode: `
19+
{
20+
data() {
21+
return {
22+
showValue: "开启预览模式后,点击我显示预设逻辑",
23+
showText: "这里的值声明于预设JS代码"
24+
};
25+
},
26+
methods: {
27+
hello() {
28+
alert("来自预设逻辑代码的问候");
29+
},
30+
},
31+
}`
32+
},
1733
}
1834
},
1935
mounted() {
2036
},
2137
methods: {
22-
onCodeUpdate(newCodeEntity) {
38+
onCodeUpdate({ codeRawVueInfo, JSCode }) {
2339
// 编辑后新的代码结构
40+
// codeRawVueInfo为template对象表示结构
41+
// JSCode为显式输入的JS逻辑
2442
}
2543
}
2644
}

src/components-v2/ToolsBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</el-col>
1717
<el-col :span="3">
1818
<div style="display:inline-block;">
19-
<el-link type="primary" @click="onEditModeChange">{{editMode ? 'View' : 'Edit'}}
19+
<el-link :type="editMode? 'primary': 'danger'" @click="onEditModeChange">{{editMode ? 'View' : 'Edit'}}
2020
Mode</el-link>
2121
</div>
2222
</el-col>

src/components-v2/VCC.vue

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
<code-structure @save="onSaveAttr" @remove="onRemove" ref="codeStructure" v-model="structureVisible"
5252
@reRender="render">
5353
</code-structure>
54-
<CodeEditor v-model:codeDialogVisible="jsDialogVisible" @saveJSCode="saveJSCode"></CodeEditor>
54+
<CodeEditor v-model:codeDialogVisible="jsDialogVisible" @saveJSCode="saveJSCode" ref="codeEditor"></CodeEditor>
5555
<VueEditor v-model:vueDialogVisible="vueDialogVisible" @codeParseSucess="codeParseSucess"></VueEditor>
5656
</div>
5757

@@ -77,7 +77,14 @@ import keymaster from "keymaster"
7777
7878
export default {
7979
name: "vcc",
80-
props: ['initCodeEntity'],
80+
props: {
81+
initCodeEntity: {
82+
type: Object,
83+
default: () => {
84+
return {};
85+
}
86+
}
87+
},
8188
emits: ['updateCodeEntity'],
8289
components: {
8390
RawComponents: defineAsyncComponent(() => import("@/components/RawComponents.vue")),
@@ -99,7 +106,10 @@ export default {
99106
iconCode: ("https://static.imonkey.xueersi.com/download/vcc-resource/icon/code-working-outline.svg"),
100107
iconClear: ("https://static.imonkey.xueersi.com/download/vcc-resource/icon/trash-outline.svg"),
101108
102-
editMode: true
109+
editMode: true,
110+
111+
codeRawVueInfo: "",
112+
JSCode: ""
103113
};
104114
},
105115
watch: {
@@ -114,8 +124,12 @@ export default {
114124
}
115125
},
116126
initCodeEntity(newVal) {
117-
if (newVal) {
118-
this.mainPanelProvider.render(newVal);
127+
if (newVal.JSCode) {
128+
this.mainPanelProvider.saveJSCodeOnly(this.convertLogicCode(newVal.JSCode));
129+
}
130+
131+
if (newVal.codeStructure) {
132+
this.mainPanelProvider.render(newVal.codeStructure);
119133
}
120134
}
121135
},
@@ -129,6 +143,7 @@ export default {
129143
mounted() {
130144
Promise.all([import("../map/load")])
131145
.then(res => {
146+
this.$emit("onLoadFinish");
132147
this.init();
133148
});
134149
splitInit();
@@ -138,6 +153,19 @@ export default {
138153
updated() { },
139154
destoryed() { },
140155
methods: {
156+
convertLogicCode(JSCode) {
157+
try {
158+
const JSCodeInfo = eval(`(function(){return ${JSCode.replace(/\s+/g, "")}})()`);
159+
// 保留JS代码
160+
this.JSCode = JSCode;
161+
if (this.$refs.codeEditor) {
162+
this.$refs.codeEditor.updateLogicCode(JSCode);
163+
}
164+
return JSCodeInfo;
165+
} catch (e) {
166+
console.warn(`外部逻辑代码解析出错,解析的逻辑代码为: ${JSCode}, Error: ${e}`);
167+
}
168+
},
141169
142170
initShortcut() {
143171
keymaster('⌘+z, ctrl+z', () => {
@@ -173,12 +201,23 @@ export default {
173201
if (this.$refs.codeStructure) {
174202
this.$refs.codeStructure.updateCode(codeRawVueInfo);
175203
}
176-
this.$emit('updateCodeEntity', codeRawVueInfo);
204+
this.codeRawVueInfo = codeRawVueInfo;
205+
206+
this.notifyParent();
177207
}).onNodeDeleted(() => {
178208
this.currentEditRawInfo = null;
179209
}).onSelectElement(rawInfo => {
180210
this.currentEditRawInfo = rawInfo;
181-
}).render(this.initCodeEntity ? this.initCodeEntity : this.getFakeData());
211+
}).saveJSCodeOnly(this.convertLogicCode(this.initCodeEntity.JSCode ? this.initCodeEntity.JSCode : ''))
212+
.render(this.initCodeEntity.codeStructure ? this.initCodeEntity.codeStructure : this.getFakeData());
213+
},
214+
215+
// 通知父组件
216+
notifyParent() {
217+
this.$emit('updateCodeEntity', {
218+
codeRawVueInfo: this.codeRawVueInfo,
219+
JSCode: this.JSCode
220+
});
182221
},
183222
184223
// 指向将要插入哪个元素之前
@@ -247,8 +286,11 @@ export default {
247286
this.mainPanelProvider.undo();
248287
},
249288
250-
saveJSCode(code) {
289+
saveJSCode({ JSCodeInfo: code, JSCode }) {
251290
this.mainPanelProvider.saveJSCode(code);
291+
// 保留JS代码
292+
this.JSCode = JSCode;
293+
this.notifyParent();
252294
},
253295
254296
/**
@@ -444,6 +486,10 @@ export default {
444486
margin: 0 2px;
445487
}
446488

489+
:root {
490+
--animate-duration: 1.5s;
491+
}
492+
447493
.in-element {
448494
outline: 2px solid #4dba87 !important;
449495
position: relative;

src/components/JSCodeEditorDialog.vue

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33
:center=true>
44
<CodeEditor style="max-height: 65vh;" ref="codeEditor" :initCode="code" mode="text/javascript"></CodeEditor>
55

6-
<div style="text-align:center;padding: 10px;">
7-
<el-button type="primary" @click="onSave">确认修改</el-button>
8-
<div style="color: #6c6c6c; font-size:12px; margin-top:5px;">Tips: 确认修改之后将会影响最终生成的代码逻辑</div>
9-
<div v-if="error" style="color: red; font-size:12px; margin-top:5px;">请检查语法错误:{{error}}</div>
6+
<div style="padding: 10px; display:flex;justify-content: flex-end;align-items: center;">
7+
<div>
8+
<el-button type="primary" @click="onSave">确认修改</el-button>
9+
<div v-if="error" style="color: red; font-size:12px; margin-top:5px;">请检查语法错误:{{error}}</div>
10+
</div>
11+
12+
<div style="margin-left: 5px;">
13+
<el-link href="https://vcc.sahadev.tech/doc/#/improve/logic?id=%e9%80%bb%e8%be%91%e6%a8%a1%e6%9d%bf"
14+
target="_blank" icon="el-icon-question">帮助与说明</el-link>
15+
<div style="color: #6c6c6c; font-size:12px; margin-top:5px;">Tips: 建议看一下使用说明</div>
16+
</div>
1017
</div>
1118
</el-dialog>
1219

@@ -16,27 +23,17 @@
1623
import dedent from 'dedent'
1724
import CodeEditor from './CodeEditor.vue'
1825
19-
export default {
20-
props: ['codeDialogVisible'],
21-
emits: ['saveJSCode', 'update:codeDialogVisible'],
22-
components: {
23-
CodeEditor
24-
},
26+
import prettier from "prettier/standalone";
27+
import babel from "prettier/parser-babel";
2528
26-
data() {
27-
return {
28-
error: '',
29-
code: dedent`
29+
const example = dedent`
3030
/**
3131
* 以下代码中的方法会被注入到最终的代码中,如果命名与源代码有相同的,则会替换源代码
3232
* 内部集成了axios,开发者可以直接通过axios发起网络请求,不过接口需要允许跨域。
3333
* 可以通过https://apis.sahadev.tech/exchange?url=的方式访问实际地址可以解决跨域问题。
3434
* axios官方文档:https://www.npmjs.com/package/axios
3535
*/
3636
{
37-
props: [],
38-
components: {},
39-
4037
data() {
4138
return {
4239
@@ -55,25 +52,21 @@ export default {
5552
axios.get('https://apis.sahadev.tech/exchange?url=https://www.baidu.com').then(res => console.info(res), err => console.error(err));
5653
}
5754
},
58-
59-
// 生命周期 start
60-
beforeCreate() {},
61-
created() {},
62-
63-
beforeMount() {},
64-
mounted() {},
65-
66-
beforeUpdate() {},
67-
updated() {},
68-
69-
beforeDestory() {},
70-
destoryed() {},
71-
// 生命周期 end
72-
73-
fillter: {},
7455
};
75-
7656
`
57+
58+
export default {
59+
props: ['codeDialogVisible'],
60+
emits: ['saveJSCode', 'update:codeDialogVisible'],
61+
components: {
62+
CodeEditor
63+
},
64+
65+
data() {
66+
return {
67+
error: '',
68+
code: example,
69+
example: `${example}`
7770
};
7871
},
7972
beforeCreate() { },
@@ -84,21 +77,28 @@ export default {
8477
updated() { },
8578
destoryed() { },
8679
methods: {
87-
// 在此自动生成
88-
request() {
89-
// 网络请求,可选
80+
updateLogicCode(newCode) {
81+
if (newCode) {
82+
const pre = "const a = ";
83+
this.code = prettier.format(pre + newCode, {
84+
plugins: [babel],
85+
}).replace(pre, "");
86+
}
9087
},
9188
handleClose() {
9289
this.$emit("update:codeDialogVisible", false);
9390
},
9491
onSave() {
9592
const code = this.$refs.codeEditor.getEditorCode();
9693
// 去掉注释
97-
const temp = code.replace(/.+\*\/\s*/gs, "");
94+
const temp = code.replace(/.+\*\/\s*/gs, "").replace(/\s+/g, "");
9895
try {
9996
// 转换为对象
10097
const JSCodeInfo = eval(`(function(){return ${temp}})()`);
101-
this.$emit("saveJSCode", JSCodeInfo);
98+
this.$emit("saveJSCode", {
99+
JSCodeInfo,
100+
JSCode: temp
101+
});
102102
this.handleClose();
103103
this.error = '';
104104
} catch (error) {

src/libs/code-generator-factory.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function createNewCodeGenerator() {
3333
const kav = methodItem.split(":");
3434
const key = kav[0];
3535
// 这里获取的是原始data数据
36-
if (window.methodSourceMap[key]) {
36+
if (window.methodSourceMap && window.methodSourceMap[key]) {
3737
return `${key}: ${window.methodSourceMap[key]}`;
3838
} else {
3939
return methodItem;
-54.6 KB
Binary file not shown.
-27.5 KB
Binary file not shown.

src/libs/element-ui/index.css

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/libs/element-ui/index.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/libs/main-panel.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,16 @@ export class MainPanelProvider {
129129
}
130130

131131
saveJSCode(code) {
132-
this.externalJS = code;
133-
this.codeGenerator.setExternalJS(code);
132+
this.saveJSCodeOnly(code);
133+
this.codeGenerator && this.codeGenerator.setExternalJS(code);
134134
this.reRender();
135135
}
136136

137+
saveJSCodeOnly(code) {
138+
this.externalJS = code || {};
139+
return this;
140+
}
141+
137142
/**
138143
* 生成一个新的待挂载容器
139144
*/
@@ -273,7 +278,12 @@ export class MainPanelProvider {
273278
enableEditMode() {
274279
const renderControlPanel = this.getControlPanelRoot();
275280
// 加一个延迟的作用是:给el-table这种绘制需要时间的组件留出充足的时间,否则会造成el-table渲染不到页面上
276-
setTimeout(() => {
281+
282+
if (this.enableDelayTask) {
283+
clearTimeout(this.enableDelayTask);
284+
}
285+
286+
this.enableDelayTask = setTimeout(() => {
277287
// 这种方式可以禁用原节点所有的事件
278288
const elClone = renderControlPanel.cloneNode(true);
279289
renderControlPanel.parentNode.replaceChild(elClone, renderControlPanel);

0 commit comments

Comments
 (0)