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

update: 集成好vuedraggable

This commit is contained in:
shangbin 2021-12-08 18:59:04 +08:00
parent 1c61f4b83a
commit b870e28608
9 changed files with 766 additions and 92 deletions

27
package-lock.json generated
View File

@ -2189,6 +2189,11 @@
}
}
},
"@vue/devtools-api": {
"version": "6.0.0-beta.20.1",
"resolved": "https://rg.cnpmjs.org/@vue/devtools-api/download/@vue/devtools-api-6.0.0-beta.20.1.tgz",
"integrity": "sha512-R2rfiRY+kZugzWh9ZyITaovx+jpU4vgivAEAiz80kvh3yviiTU3CBuGuyWpSwGz9/C7TkSWVM/FtQRGlZ16n8Q=="
},
"@vue/eslint-config-airbnb": {
"version": "5.3.0",
"resolved": "https://r.cnpmjs.org/@vue/eslint-config-airbnb/download/@vue/eslint-config-airbnb-5.3.0.tgz",
@ -11934,6 +11939,11 @@
}
}
},
"sortablejs": {
"version": "1.14.0",
"resolved": "https://rg.cnpmjs.org/sortablejs/download/sortablejs-1.14.0.tgz",
"integrity": "sha1-bS4XzL2yX0ZHNN9iHU811Ks1s9g="
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://r.cnpmjs.org/source-list-map/download/source-list-map-2.0.1.tgz",
@ -13347,10 +13357,21 @@
"integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true
},
"vuedraggable": {
"version": "4.1.0",
"resolved": "https://rg.cnpmjs.org/vuedraggable/download/vuedraggable-4.1.0.tgz",
"integrity": "sha1-7ezmituKTZ4GrM/538kEDmaFInA=",
"requires": {
"sortablejs": "1.14.0"
}
},
"vuex": {
"version": "3.6.2",
"resolved": "https://r.cnpmjs.org/vuex/download/vuex-3.6.2.tgz",
"integrity": "sha1-I2vAhqhww655lG8QfxbeWdWJXnE="
"version": "4.0.2",
"resolved": "https://rg.cnpmjs.org/vuex/download/vuex-4.0.2.tgz",
"integrity": "sha1-+Jbb1b8qDpY/AMZ+m2EN50nMrMk=",
"requires": {
"@vue/devtools-api": "^6.0.0-beta.11"
}
},
"watchpack": {
"version": "1.7.5",

View File

@ -62,7 +62,8 @@
"vue": "^3.2.22",
"vue-nestable": "^2.6.0",
"vue-router": "^3.4.9",
"vuex": "^3.1.2"
"vuedraggable": "^4.1.0",
"vuex": "^4.0.2"
},
"devDependencies": {
"@babel/generator": "^7.11.6",

View File

@ -16,8 +16,7 @@
</div>
</div>
<attribute-input :enableRemoveButton="true" class="attribute" @save="onSaveAttr" @remove="onRemove"
ref="attributeInput" shortcutInitMode="hand" @codeRefresh="generateVueCode"
:__rawVueInfo__="currentEditRawInfo">
ref="attributeInput" shortcutInitMode="hand" :__rawVueInfo__="currentEditRawInfo">
</attribute-input>
</div>
</div>
@ -50,7 +49,7 @@
<lc-code :rawCode="code" v-model:codeDialogVisible="codeDialogVisible">
</lc-code>
<code-structure @save="onSaveAttr" @remove="onRemove" ref="codeStructure" v-model="structureVisible"
@codeRefresh="generateVueCode" @onLevelChange="onLevelChange">
@reRender="render">
</code-structure>
<CodeEditor v-model:codeDialogVisible="jsDialogVisible" @saveJSCode="saveJSCode"></CodeEditor>
<VueEditor v-model:vueDialogVisible="vueDialogVisible" @codeParseSucess="codeParseSucess"></VueEditor>
@ -220,11 +219,6 @@ export default {
this.mainPanelProvider.saveAttribute(resultList, lc_id);
},
onLevelChange(removeID, movePath) {
this.mainPanelProvider.onLevelChange(removeID, movePath);
},
generateVueCode() { },
onRemove({ lc_id }) {
this.mainPanelProvider.remove(lc_id);
},
@ -240,10 +234,20 @@ export default {
this.mainPanelProvider.saveJSCode(code);
},
/**
* 二级编辑解析
*/
codeParseSucess(vueCodeEntity) {
this.mainPanelProvider.render(vueCodeEntity);
},
/**
* 渲染指定结构
*/
render(codeEntity) {
this.mainPanelProvider.render(codeEntity);
},
help() {
window.open('/doc')
}

View File

@ -1,7 +1,7 @@
<template>
<el-card class="attribute-container">
<div style="text-algin: center;">
<div style="text-align: center;">
<el-switch v-model="editMode" active-text="自由编辑" inactive-text="约束编辑" active-color="#13ce66"
inactive-color="#13ce66">
</el-switch>
@ -197,7 +197,7 @@ export default {
},
copyBro() {
copyBroCode(this.__rawVueInfo__);
this.$emit('codeRefresh');
this.$store.commit('onDragEnd');
},
onShow() {
//

View File

@ -2,7 +2,7 @@
<el-drawer v-model="drawer" :with-header="false" size="70%" direction="btt">
<div class="container">
<div style="text-algin: center;">组件结构检视图
<div style="text-align: center;">组件结构检视图
<br>
<span style="font-size:12px;">Components
Structure</span>
@ -12,26 +12,13 @@
<el-col :span="16" style="height: 100%;">
<div style="overflow: scroll;height:100%; margin: 0 20px;padding: 10px;">
<!-- <vue-nestable v-model="treeData" @change="onLevelChange">
<template v-slot="{ item }">
<vue-nestable-handle :item="item">
<el-icon class="icon-s"><rank /></el-icon>
</vue-nestable-handle>
<span @click="onNodeClick(item)">{{ item.text }}</span>
</template>
<template v-slot:placeholder>
<div><b>The editor is empty.</b></div>
</template>
</vue-nestable> -->
<nested-draggable :data="treeData" />
</div>
</el-col>
<el-col :span="8">
<attribute-input ref="attributeInput" :enableRemoveButton="true" v-if="currentEditRawInfo && drawer"
@save="onSaveAttr" shortcutInitMode="auto" @remove="onRemove" @codeRefresh="codeRefresh"
:__rawVueInfo__="currentEditRawInfo">
<attribute-input ref="attributeInput" :enableRemoveButton="true" v-if="currentEditRawInfo" @save="onSaveAttr"
shortcutInitMode="auto" @remove="onRemove" :__rawVueInfo__="currentEditRawInfo">
</attribute-input>
</el-col>
</el-row>
@ -41,81 +28,33 @@
</template>
<script>
import "./halower-tree.min.css";
import "@/assets/nestable.css"
import { isObject, getRawComponentKey, getRawComponentContent } from "@/utils/common";
// import { VueNestable, VueNestableHandle } from 'vue-nestable';
import nestedDraggable from './nested.vue'
import { defineAsyncComponent } from 'vue'
export default {
props: ['visible'],
emits: ['codeRefresh', 'onLevelChange', 'remove', 'save', 'update:visible'],
emits: ['onLevelChange', 'remove', 'save', 'update:visible', 'reRender'],
components: {
AttributeInput: resolve => { require(["./AttributeInput"], resolve) },
// VueNestable,
// VueNestableHandle
AttributeInput: defineAsyncComponent(() => import("@/components/AttributeInput.vue")),
nestedDraggable
},
data() {
return {
//
treeData: [],
currentEditRawInfo: null
};
},
beforeCreate() { },
created() { },
beforeMount() { },
mounted() { },
mounted() {
},
beforeUpdate() { },
updated() { },
destoryed() { },
methods: {
//
request() {
//
},
codeRefresh() {
this.$emit('codeRefresh');
},
onLevelChange(value, options) {
this.$emit('onLevelChange', value.id, options.pathTo);
},
convertStructure(rawInfo) {
const title = getRawComponentKey(rawInfo);
const object = rawInfo[title];
const children = [];
if (isObject(object)) {
for (const key in object) {
if (object.hasOwnProperty(key)) {
if (key === '__children') {
const element = object[key];
element.forEach(item => {
const temp = this.convertStructure(item);
temp && children.push(temp);
})
} else if (isObject(object[key])) {
//
const __obj = {};
__obj[key] = object[key];
const child = this.convertStructure(__obj);
child && children.push(child);
}
}
}
return {
text: title,
expanded: true,
children: children,
rawInfo: rawInfo,
id: getRawComponentContent(rawInfo).lc_id
}
} else {
return null;
}
},
onNodeClick(nodeInfo) {
this.currentEditRawInfo = nodeInfo.rawInfo;
@ -131,12 +70,17 @@ export default {
},
updateCode(codeRawInfo) {
this.treeData = [this.convertStructure(codeRawInfo)];
this._codeRawInfo = codeRawInfo;
const content = getRawComponentContent(codeRawInfo);
const children = content.__children;
this.treeData = children;
},
},
watch: {
canInitShortcut(newValue) {
renderCount(){
// vuedraggable v-model
this.$emit('reRender', this._codeRawInfo);
}
},
computed: {
@ -148,8 +92,21 @@ export default {
this.$emit('update:visible', false);
}
},
renderCount(){
return this.$store.state.renderCount;
},
canInitShortcut() {
return this.currentEditRawInfo !== null && this.drawer;
},
currentEditRawInfo() {
if (this.$store.state.currentEditComp) {
const vccData = this.$store.state.currentEditComp.vccData;
return window.tree[vccData.lc_id];
} else {
return null;
}
}
},
fillter: {},

File diff suppressed because one or more lines are too long

89
src/components/nested.vue Normal file
View File

@ -0,0 +1,89 @@
<template>
<draggable class="dragArea" tag="ul" :list="data" @start="onStartDrag" @choose="onClick"
@end="onEndDrag">
<template #item="{ element }">
<li class="itemArea">
<p>{{ getRawComponentKey(element) }}</p>
<nested-draggable :data="getRawComponentContent(element).__children" />
</li>
</template>
</draggable>
</template>
<script>
import draggable from "vuedraggable";
import { getRawComponentKey, getRawComponentContent } from "@/utils/common";
export default {
props: {
data: {
required: true,
type: Array
}
},
data() {
return {
}
},
computed: {
},
methods: {
getRawComponentKey,
getRawComponentContent,
onStartDrag(event) {
event.item.classList.add("is-dragging");
},
onClick(event) {
if(this.$store.state.currentEditComp){
this.$store.state.currentEditComp.item.classList.remove("is-dragging");
}
event.item.classList.add("is-dragging");
event.vccData = getRawComponentContent(this.data[event.oldIndex]);
this.$store.commit('storeCurrentEditComp', event);
},
onEndDrag(event) {
event.item.classList.remove("is-dragging");
this.$store.commit('onDragEnd');
}
},
components: {
draggable
},
name: "nested-draggable"
};
</script>
<style scoped lang="scss">
.dragArea {
min-height: 20px;
border: 1px dashed rgb(126, 126, 128);
border-radius: 5px;
padding-inline-start: 30px;
padding-right: 2px;
padding-bottom: 2px;
}
p {
margin: 10px 0;
}
.itemArea {
min-height: 20px;
border: 1px dashed rgb(126, 126, 128);
padding-right: 2px;
padding-bottom: 2px;
border-radius: 5px;
padding-inline-start: 10px;
margin: 10px 0 0;
}
.is-dragging {
background-color: rgba(106, 127, 233, 0.274);
border: 1px dashed rgb(73, 100, 241);
-webkit-border-radius: 5px;
border-radius: 5px;
}
</style>

24
src/libs/store.js Normal file
View File

@ -0,0 +1,24 @@
import { createStore } from 'vuex'
const store = createStore({
state() {
return {
count: 0,
currentEditComp: null,
renderCount: 0
}
},
mutations: {
increment(state) {
state.count++
},
storeCurrentEditComp(state, newComp) {
state.currentEditComp = newComp;
},
onDragEnd(state) {
state.renderCount++;
}
}
})
globalApp.use(store);

View File

@ -1,4 +1,4 @@
import { createApp, compile } from "vue";
import { createApp } from "vue";
import ElementPlus from "element-plus";
import { QuestionFilled, CirclePlus, DocumentCopy, Delete, Refresh, Minus } from "@element-plus/icons";
@ -19,8 +19,12 @@ function createBaseApp(renderComponent = {}) {
return app;
}
createBaseApp(APP).mount("#app");
const globalApp = createBaseApp(APP)
globalApp.mount("#app");
// 内部需要同样配置的全局Vue
self.createBaseApp = createBaseApp;
self.compile = compile;
self.globalApp = globalApp; // 内部需要使用Vuex
import("@/libs/store.js");