add:完善组件删除功能
This commit is contained in:
3
auto-imports.d.ts
vendored
3
auto-imports.d.ts
vendored
@ -3,6 +3,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// noinspection JSUnusedGlobalSymbols
|
// noinspection JSUnusedGlobalSymbols
|
||||||
// Generated by unplugin-auto-import
|
// Generated by unplugin-auto-import
|
||||||
|
// biome-ignore lint: disable
|
||||||
export {}
|
export {}
|
||||||
declare global {
|
declare global {
|
||||||
const EffectScope: typeof import('vue')['EffectScope']
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
@ -303,6 +304,6 @@ declare global {
|
|||||||
// for type re-export
|
// for type re-export
|
||||||
declare global {
|
declare global {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||||
import('vue')
|
import('vue')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
</VueDraggable>
|
</VueDraggable>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<PropertyEditor :scheme="store.nowComponentsData"></PropertyEditor>
|
<PropertyEditor v-if="store.nowComponentsData" :scheme="store.nowComponentsData"></PropertyEditor>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -76,9 +76,9 @@ import axios from 'axios';
|
|||||||
let componentsList = [];
|
let componentsList = [];
|
||||||
const store = useSchemeStore();
|
const store = useSchemeStore();
|
||||||
|
|
||||||
// watch(store, (n) => {
|
watch(store, (n) => {
|
||||||
// console.log("store发生了变化", n);
|
console.log("store发生了变化", n);
|
||||||
// });
|
});
|
||||||
|
|
||||||
const baseScheme = {
|
const baseScheme = {
|
||||||
"type": "AdaptivePage",
|
"type": "AdaptivePage",
|
||||||
@ -157,24 +157,24 @@ function clone(element: Record<'name' | 'id' | 'type' | 'props' | 'class' | 'tex
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onEnd = (event: DraggableEvent) => {
|
const onEnd = (event: DraggableEvent) => {
|
||||||
console.log("onEnd", event);
|
// console.log("onEnd", event);
|
||||||
store.nowComponentsData = event.clonedData;
|
store.nowComponentsData = event.clonedData;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStart = (event) => {
|
const onStart = (event) => {
|
||||||
console.log("onStart", event);
|
// console.log("onStart", event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPreviewStart = (event) => {
|
const onPreviewStart = (event) => {
|
||||||
console.log("onPreviewStart", event);
|
// console.log("onPreviewStart", event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPreviewUpdate = (event) => {
|
const onPreviewUpdate = (event) => {
|
||||||
console.log("onPreviewUpdate", event);
|
// console.log("onPreviewUpdate", event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPreviewStop = (event) => {
|
const onPreviewStop = (event) => {
|
||||||
console.log(event);
|
// console.log(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
style="width: fit-content; display: flex; flex-direction: column; position: relative;"
|
style="width: fit-content; display: flex; flex-direction: column; position: relative;"
|
||||||
v-if="componentVisible || store.designerMode"
|
v-if="store.nowComponentsData!==null&&(componentVisible || store.designerMode)"
|
||||||
:id="componentId"
|
:id="componentId"
|
||||||
:class="[
|
:class="[
|
||||||
'dynamic-component',
|
'dynamic-component',
|
||||||
{ 'hover-state': isHovered },
|
{ 'hover-state': isHovered },
|
||||||
{ 'click-state': isClicked }
|
{ 'click-state': componentSelected }
|
||||||
]"
|
]"
|
||||||
@click.stop="handleClick"
|
@click.stop="handleClick"
|
||||||
@mouseover="isHovered = true"
|
@mouseover="isHovered = true"
|
||||||
@mouseleave="isHovered = false"
|
@mouseleave="isHovered = false"
|
||||||
>
|
>
|
||||||
<div v-if="isClicked" class="component-header" :style="headerStyle">
|
<div v-if="componentSelected" class="component-header" :style="headerStyle">
|
||||||
<span>{{ componentName }}</span>
|
<span>{{ componentName }}</span>
|
||||||
<button style="color: #1057CC" @click="handleFunction('edit')">编辑</button>
|
<button style="color: #1057CC" @click="handleEditFunc">编辑</button>
|
||||||
<button style="color: #1057CC" @click="handleFunction('delete')">删除</button>
|
<button style="color: #1057CC" @click="handleDeleteFunc">删除</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="component-content">
|
<div class="component-content">
|
||||||
<component
|
<component
|
||||||
@ -26,10 +26,10 @@
|
|||||||
>
|
>
|
||||||
{{ componentText }}
|
{{ componentText }}
|
||||||
<template v-for="child in componentChildren" :key="child.id">
|
<template v-for="child in componentChildren" :key="child.id">
|
||||||
<DynamicComponent :componentData="child" />
|
<DynamicComponent :componentData="child"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="(slot, key, index) in componentSlots" :key="index" v-slot:[key]>
|
<template v-for="(slot, key, index) in componentSlots" :key="index" v-slot:[key]>
|
||||||
<DynamicComponent :component-data="slot" />
|
<DynamicComponent :component-data="slot"/>
|
||||||
</template>
|
</template>
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
@ -37,9 +37,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineProps, ref, computed, onMounted, watch, markRaw, nextTick } from 'vue';
|
import {defineProps, ref, computed, onMounted, watch, markRaw, nextTick} from 'vue';
|
||||||
import { componentMapping } from './componentMapping';
|
import {componentMapping} from './componentMapping';
|
||||||
import { useSchemeStore } from '../stores/useSchemeStore';
|
import {useSchemeStore} from '../stores/useSchemeStore';
|
||||||
|
|
||||||
const store = useSchemeStore();
|
const store = useSchemeStore();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -57,6 +57,7 @@ const componentText = computed(() => props.componentData?.text || '');
|
|||||||
const componentClass = computed(() => props.componentData?.class || []);
|
const componentClass = computed(() => props.componentData?.class || []);
|
||||||
const componentStyle = computed(() => props.componentData?.style || []);
|
const componentStyle = computed(() => props.componentData?.style || []);
|
||||||
const componentSlots = computed(() => props.componentData?.slots || {});
|
const componentSlots = computed(() => props.componentData?.slots || {});
|
||||||
|
const componentSelected = computed(() => store.nowComponentsData?.id && props.componentData?.id === store.nowComponentsData?.id);
|
||||||
|
|
||||||
// 确保 componentProps 包含 disabled 属性
|
// 确保 componentProps 包含 disabled 属性
|
||||||
const componentPropsWithDisabled = computed(() => ({
|
const componentPropsWithDisabled = computed(() => ({
|
||||||
@ -71,24 +72,24 @@ const getCurrentSchemeObj = () => {
|
|||||||
|
|
||||||
// 控制悬停和点击状态
|
// 控制悬停和点击状态
|
||||||
const isHovered = ref(false);
|
const isHovered = ref(false);
|
||||||
const isClicked = ref(false);
|
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
isClicked.value = !isClicked.value;
|
|
||||||
const currentComponent = getCurrentSchemeObj();
|
const currentComponent = getCurrentSchemeObj();
|
||||||
console.log(`Component with id ${currentComponent.id} was clicked.`);
|
if (currentComponent) {
|
||||||
// 你可以在这里执行更多的逻辑,例如发出一个事件或调用一个方法
|
store.nowComponentsData = currentComponent
|
||||||
};
|
console.log(`Component with id ${currentComponent?.id} was clicked.`);
|
||||||
|
// 你可以在这里执行更多的逻辑,例如发出一个事件或调用一个方法
|
||||||
|
}
|
||||||
|
|
||||||
const handleFunction = (action: string) => {
|
};
|
||||||
console.log(`Action: ${action}`);
|
const handleEditFunc = () => {
|
||||||
// 处理编辑或删除操作
|
|
||||||
|
};
|
||||||
|
const handleDeleteFunc = () => {
|
||||||
|
store.deleteScheme(componentId.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerStyle = ref({});
|
const headerStyle = ref({});
|
||||||
|
|
||||||
const targetContent = ref<HTMLElement | null>(null);
|
|
||||||
|
|
||||||
const adjustHeaderPosition = () => {
|
const adjustHeaderPosition = () => {
|
||||||
const componentEl = document.getElementById(componentId.value);
|
const componentEl = document.getElementById(componentId.value);
|
||||||
if (!componentEl) return;
|
if (!componentEl) return;
|
||||||
@ -137,11 +138,10 @@ const adjustHeaderPosition = () => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(props.componentData);
|
console.log(props.componentData);
|
||||||
adjustHeaderPosition();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => isClicked.value, () => {
|
watch(() => componentSelected.value, () => {
|
||||||
if (isClicked.value) {
|
if (componentSelected.value) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
adjustHeaderPosition();
|
adjustHeaderPosition();
|
||||||
});
|
});
|
||||||
@ -153,7 +153,7 @@ watch(() => isClicked.value, () => {
|
|||||||
.dynamic-component {
|
.dynamic-component {
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid transparent; /* 默认透明边框 */
|
border: 1px solid transparent; /* 默认透明边框 */
|
||||||
transition: border 0.3s, box-shadow 0.3s;
|
transition: box-shadow 0.1s;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,25 +14,25 @@
|
|||||||
<div style="margin-top: 16px;">
|
<div style="margin-top: 16px;">
|
||||||
<!-- 属性面板 -->
|
<!-- 属性面板 -->
|
||||||
<div>
|
<div>
|
||||||
<a-input-search placeholder="Please enter something" />
|
<a-input-search placeholder="Please enter something"/>
|
||||||
<a-space direction="vertical" fill style="margin-top: 8px;">
|
<a-space direction="vertical" fill style="margin-top: 8px;">
|
||||||
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
||||||
<span>组件ID</span>
|
<span>组件ID</span>
|
||||||
<a-input style="width: 150px;" />
|
<a-input style="width: 150px;"/>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
||||||
<span>是否可见</span>
|
<span>是否可见</span>
|
||||||
<a-switch v-model="scheme.visible" />
|
<a-switch v-model="scheme.visible"/>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
||||||
<span>是否禁用</span>
|
<span>是否禁用</span>
|
||||||
<a-switch v-model="scheme.disable" />
|
<a-switch v-model="scheme.disable"/>
|
||||||
</div>
|
</div>
|
||||||
<a-collapse :expand-icon-position="`right`" :default-active-key="['1', 2]">
|
<a-collapse :expand-icon-position="`right`" :default-active-key="['1', 2]">
|
||||||
<a-collapse-item header="基本配置" key="1">
|
<a-collapse-item header="基本配置" key="1">
|
||||||
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
<div style="display: flex;justify-content: space-between;vertical-align: middle;">
|
||||||
<span>内容</span>
|
<span>内容</span>
|
||||||
<a-input v-model="scheme.text" style="width: 150px;" />
|
<a-input v-model="scheme.text" style="width: 150px;"/>
|
||||||
</div>
|
</div>
|
||||||
</a-collapse-item>
|
</a-collapse-item>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
@ -60,9 +60,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { watch, defineProps, computed, ref, onMounted } from 'vue';
|
import {watch, defineProps, computed, ref, onMounted} from 'vue';
|
||||||
import { IPageComponent } from '@/type/IPageComponent';
|
import {IPageComponent} from '@/type/IPageComponent';
|
||||||
import { useSchemeStore } from '../stores/useSchemeStore'
|
import {useSchemeStore} from '../stores/useSchemeStore'
|
||||||
|
|
||||||
import {IComponent} from "@/type/IComponent.ts";
|
import {IComponent} from "@/type/IComponent.ts";
|
||||||
|
|
||||||
@ -79,8 +79,9 @@ const scheme = computed<IPageComponent>(() => props.scheme || {} as IPageCompone
|
|||||||
// 使用 deep 选项来深度监听对象的变化
|
// 使用 deep 选项来深度监听对象的变化
|
||||||
watch(scheme, (value, oldValue) => {
|
watch(scheme, (value, oldValue) => {
|
||||||
console.log("scheme Changed", value);
|
console.log("scheme Changed", value);
|
||||||
store.updateScheme(value.id,value as IComponent);
|
if (value)
|
||||||
}, { deep: true });
|
store.updateScheme(value.id, value as IComponent);
|
||||||
|
}, {deep: true});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 初始化时的逻辑
|
// 初始化时的逻辑
|
||||||
|
|||||||
@ -5,19 +5,20 @@ import { sha256 } from 'js-sha256';
|
|||||||
// 缓存对象
|
// 缓存对象
|
||||||
const idToObjectCache = new Map<string, IPageComponent>();
|
const idToObjectCache = new Map<string, IPageComponent>();
|
||||||
|
|
||||||
function findObjectById(obj, targetId) {
|
function findObjectById(obj: any, targetId: string) {
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
for (let item of obj) {
|
for (let i = 0; i < obj.length; i++) {
|
||||||
let found = findObjectById(item, targetId);
|
const item = obj[i];
|
||||||
|
if (item.id === targetId) {
|
||||||
|
return { item, index: i, parent: obj };
|
||||||
|
}
|
||||||
|
const found = findObjectById(item, targetId);
|
||||||
if (found) return found;
|
if (found) return found;
|
||||||
}
|
}
|
||||||
} else if (typeof obj === 'object' && obj !== null) {
|
} else if (typeof obj === 'object' && obj !== null) {
|
||||||
if (obj.id === targetId) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
for (let key in obj) {
|
for (let key in obj) {
|
||||||
if (obj.hasOwnProperty(key)) {
|
if (obj.hasOwnProperty(key)) {
|
||||||
let found = findObjectById(obj[key], targetId);
|
const found = findObjectById(obj[key], targetId);
|
||||||
if (found) return found;
|
if (found) return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,9 +31,9 @@ const HISTORY_LENGTH = 20; // 默认队列长度
|
|||||||
export const useSchemeStore = defineStore('scheme', {
|
export const useSchemeStore = defineStore('scheme', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
designerMode: true,
|
designerMode: true,
|
||||||
components: [],
|
components: [] as IPageComponent[],
|
||||||
previewScheme: [],
|
previewScheme: [] as IPageComponent[],
|
||||||
nowComponentsData: {},
|
nowComponentsData: {} as IPageComponent,
|
||||||
history: Array(HISTORY_LENGTH).fill(null), // 循环队列
|
history: Array(HISTORY_LENGTH).fill(null), // 循环队列
|
||||||
currentIndex: -1, // 当前索引
|
currentIndex: -1, // 当前索引
|
||||||
currentLength: 0, // 当前队列中有效元素的数量
|
currentLength: 0, // 当前队列中有效元素的数量
|
||||||
@ -43,19 +44,19 @@ export const useSchemeStore = defineStore('scheme', {
|
|||||||
canRedo: (state) => state.currentIndex < state.currentLength - 1,
|
canRedo: (state) => state.currentIndex < state.currentLength - 1,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
initPreviewScheme(value) {
|
initPreviewScheme(value: IPageComponent[]) {
|
||||||
this.previewScheme = value;
|
this.previewScheme = value;
|
||||||
this.nowComponentsData = value[0];
|
this.nowComponentsData = value[0] || {} as IPageComponent;
|
||||||
idToObjectCache.clear();
|
idToObjectCache.clear();
|
||||||
this.history.fill(null); // 初始化队列
|
this.history.fill(null); // 初始化队列
|
||||||
this.currentIndex = -1;
|
this.currentIndex = -1;
|
||||||
this.currentLength = 0;
|
this.currentLength = 0;
|
||||||
this.currentHash = ''; // 初始化当前哈希值
|
this.currentHash = ''; // 初始化当前哈希值
|
||||||
},
|
},
|
||||||
initComponents(value) {
|
initComponents(value: IPageComponent[]) {
|
||||||
this.components = value;
|
this.components = value;
|
||||||
},
|
},
|
||||||
getSchemeObj(id) {
|
getSchemeObj(id: string) {
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
if (idToObjectCache.has(id)) {
|
if (idToObjectCache.has(id)) {
|
||||||
return idToObjectCache.get(id);
|
return idToObjectCache.get(id);
|
||||||
@ -63,19 +64,78 @@ export const useSchemeStore = defineStore('scheme', {
|
|||||||
// 查找并缓存
|
// 查找并缓存
|
||||||
const obj = findObjectById(this.previewScheme, id);
|
const obj = findObjectById(this.previewScheme, id);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
idToObjectCache.set(id, obj);
|
idToObjectCache.set(id, obj.item);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj ? obj.item : null;
|
||||||
},
|
},
|
||||||
updateScheme(id, updates) {
|
updateScheme(id: string, updates: Partial<IPageComponent>) {
|
||||||
const currentStateHash = this.currentHash;
|
const currentStateHash = this.currentHash;
|
||||||
const newObj = this.getSchemeObj(id);
|
const newObj = this.getSchemeObj(id);
|
||||||
if (newObj) {
|
if (newObj) {
|
||||||
Object.assign(newObj, updates);
|
Object.assign(newObj, updates);
|
||||||
}
|
}
|
||||||
const newStateHash = sha256(JSON.stringify(this.previewScheme));
|
this.saveNewState(currentStateHash);
|
||||||
|
},
|
||||||
|
deleteScheme(id: string) {
|
||||||
|
const currentStateHash = this.currentHash;
|
||||||
|
const objToDelete = findObjectById(this.previewScheme, id);
|
||||||
|
if (objToDelete) {
|
||||||
|
const { item, index, parent } = objToDelete;
|
||||||
|
parent.splice(index, 1);
|
||||||
|
idToObjectCache.delete(id); // 从缓存中删除
|
||||||
|
|
||||||
// 如果新状态与当前状态不同,才保存到历史记录中
|
// 清理 nowComponentsData
|
||||||
|
if (this.nowComponentsData.id === id) {
|
||||||
|
this.nowComponentsData = {} as IPageComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理 history 中的引用
|
||||||
|
this.cleanupReferences(id);
|
||||||
|
}
|
||||||
|
this.saveNewState(currentStateHash);
|
||||||
|
},
|
||||||
|
cleanupReferences(id: string) {
|
||||||
|
// 清理 nowComponentsData
|
||||||
|
if (this.nowComponentsData.id === id) {
|
||||||
|
this.nowComponentsData = {} as IPageComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理 history 中的引用
|
||||||
|
for (let i = 0; i < this.currentLength; i++) {
|
||||||
|
const historyState = this.history[i % HISTORY_LENGTH];
|
||||||
|
if (historyState) {
|
||||||
|
const obj = findObjectById(historyState, id);
|
||||||
|
if (obj) {
|
||||||
|
const { parent, index } = obj;
|
||||||
|
parent.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
undo() {
|
||||||
|
if (this.canUndo) {
|
||||||
|
this.currentIndex--;
|
||||||
|
const prevState = this.history[this.currentIndex % HISTORY_LENGTH];
|
||||||
|
if (prevState) {
|
||||||
|
this.previewScheme = prevState;
|
||||||
|
this.nowComponentsData = this.previewScheme[0] || {} as IPageComponent;
|
||||||
|
this.currentHash = sha256(JSON.stringify(this.previewScheme));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
redo() {
|
||||||
|
if (this.canRedo) {
|
||||||
|
this.currentIndex++;
|
||||||
|
const nextState = this.history[this.currentIndex % HISTORY_LENGTH];
|
||||||
|
if (nextState) {
|
||||||
|
this.previewScheme = nextState;
|
||||||
|
this.nowComponentsData = this.previewScheme[0] || {} as IPageComponent;
|
||||||
|
this.currentHash = sha256(JSON.stringify(this.previewScheme));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveNewState(currentStateHash: string) {
|
||||||
|
const newStateHash = sha256(JSON.stringify(this.previewScheme));
|
||||||
if (currentStateHash !== newStateHash) {
|
if (currentStateHash !== newStateHash) {
|
||||||
this.currentHash = newStateHash;
|
this.currentHash = newStateHash;
|
||||||
// 如果不是最新的状态,则清除之后的所有状态
|
// 如果不是最新的状态,则清除之后的所有状态
|
||||||
@ -87,28 +147,6 @@ export const useSchemeStore = defineStore('scheme', {
|
|||||||
this.currentLength = this.currentIndex + 1;
|
this.currentLength = this.currentIndex + 1;
|
||||||
this.history[this.currentIndex % HISTORY_LENGTH] = JSON.parse(JSON.stringify(this.previewScheme));
|
this.history[this.currentIndex % HISTORY_LENGTH] = JSON.parse(JSON.stringify(this.previewScheme));
|
||||||
}
|
}
|
||||||
},
|
|
||||||
undo() {
|
|
||||||
if (this.canUndo) {
|
|
||||||
this.currentIndex--;
|
|
||||||
const prevState = this.history[this.currentIndex % HISTORY_LENGTH];
|
|
||||||
if (prevState) {
|
|
||||||
this.previewScheme = prevState;
|
|
||||||
this.nowComponentsData = this.previewScheme[0];
|
|
||||||
this.currentHash = sha256(JSON.stringify(this.previewScheme));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
redo() {
|
|
||||||
if (this.canRedo) {
|
|
||||||
this.currentIndex++;
|
|
||||||
const nextState = this.history[this.currentIndex % HISTORY_LENGTH];
|
|
||||||
if (nextState) {
|
|
||||||
this.previewScheme = nextState;
|
|
||||||
this.nowComponentsData = this.previewScheme[0];
|
|
||||||
this.currentHash = sha256(JSON.stringify(this.previewScheme));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user