Commit 6cd8cf2b authored by 张晨辰's avatar 张晨辰

feat: 撤销重做&属性值undefined问题修复

parent f87bd87a
......@@ -22,6 +22,8 @@ const defaultOptions = {
tpl: template,
};
const OPERATE_MAX_LENGTH = 200; // 撤销重做栈最大值
function getDefaultOptions() {
return JSON.parse(JSON.stringify(defaultOptions));
}
......@@ -103,10 +105,10 @@ export const projectStore = {
// 则把操作index之后的数据都丢弃
state.operateStack = state.operateStack.slice(state.stackIndex);
}
let _last_operate = state.operateStack[0];
// 上一次的操作和最新一次操作uuid不同,表示发生了不同视图的操作
// 需要记录当前视图的原始数据
if (_last_operate.uuid !== oldView.uuid) {
let lastOperate = state.operateStack[0];
// // 上一次的操作和最新一次操作uuid不同,表示发生了不同视图的操作
// // 需要记录当前视图的原始数据
if (lastOperate.uuid !== oldView.uuid) {
state.operateStack.unshift(_.cloneDeep(oldView));
}
} else {
......@@ -116,25 +118,49 @@ export const projectStore = {
}
state.stackIndex = 0; // 开始编辑的时候,重置操作栈的下标
let newView = _.merge(oldView, view);
let newView = _.merge({}, oldView, view);
// 如果是scripts和events的修改,直接覆盖 不merge
if (view.scripts) {
newView.scripts = _.cloneDeep(view.scripts)
newView.scripts = _.cloneDeep(view.scripts);
}
if (view.events) {
newView.events = _.cloneDeep(view.events)
newView.events = _.cloneDeep(view.events);
}
// 修改properties时,做减量操作,判断是否有属性的值被清空
if (view.properties) {
newView.properties = _.cloneDeep(view.properties);
_.forIn(newView.properties, (value, key) => {
if (value === null || value === undefined) {
delete newView.properties[key];
}
});
}
if (view.type) {
// view.type有值说明修改了节点的类型
// 如果修改了节点类型,需要删除无用的属性
let defaultProps = Object.keys(getCmpProps(view.type));
_.forIn(newView.properties, (value, key) => {
if (defaultProps.indexOf(key) === -1) {
delete newView.properties[key];
}
});
}
console.log('newView', newView);
// curOperate.push(_.cloneDeep(newView)) // 保存操作之后的配置
// 在操作栈中插入最新值
state.operateStack.unshift(_.cloneDeep(_.assign({ uuid: newView.uuid }, view)));
// 操作栈最大200
if (state.operateStack.length > 200) {
state.operateStack.unshift(_.cloneDeep(newView));
// 超过最大保存数就丢弃
if (state.operateStack.length > OPERATE_MAX_LENGTH) {
state.operateStack.pop();
}
// 将数据更新至当前选中的节点上
_.forIn(view, (value, key) => {
_.forIn(newView, (value, key) => {
// if (key === 'properties') {
// horizonCenter和left\right
// verticalCenter和top\bottom
......@@ -165,20 +191,7 @@ export const projectStore = {
// }
Vue.set(state.activeComponent, key, newView[key]);
})
if (view.type) {
// view.type有值说明修改了节点的类型
// 如果修改了节点类型,需要删除无用的属性
let defaultProps = Object.keys(getCmpProps(view.type));
let _properties = _.cloneDeep(state.activeComponent.properties);
_.forIn(_properties, (value, key, prop) => {
if (defaultProps.indexOf(key) === -1) {
delete prop[key];
}
});
Vue.set(state.activeComponent, 'properties', _properties);
}
});
// 同步修改镜像节点
state.activeComponentCopy = _.cloneDeep(state.activeComponent);
......@@ -222,9 +235,13 @@ export const projectStore = {
if (_operate) {
let _cmp = getCmpByUUID(_operate.uuid, state.data.views);
if (_cmp) {
_cmp = _.merge(_cmp, _operate);
if (_operate.uuid === state.activeComponentCopy.uuid) {
state.activeComponentCopy = _.cloneDeep(_cmp)
_.forIn(_operate, (value, key) => {
_cmp[key] = value;
});
// _cmp = _.cloneDeep(_operate); //_.merge(_cmp, _operate);
if (_operate.uuid === state.activeComponent.uuid) {
state.activeComponentCopy = _.cloneDeep(_operate);
state.activeComponent = _.cloneDeep(_operate);
}
}
}
......@@ -364,7 +381,6 @@ export const projectStore = {
} else {
_view = state.data.views.length ? [].concat(state.data.views[0]) : [];
}
console.log('_view', _view);
return _view;
}
......@@ -437,10 +453,14 @@ export const projectStore = {
modifyProperties({ commit, state, getters }, props) {
// debugger;
// 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度
if (props.source) {
let _props = state.activeComponent.properties;
let _props = _.cloneDeep(state.activeComponent.properties);
_.forIn(props, (value, key) => {
_props[key] = value;
});
if (_props.source) {
if (!_props.width || !_props.height) {
let _url = props.source; //_source.value;
let _url = _props.source; //_source.value;
if (_url.indexOf('asset://') === 0) {
let uuid = _url.split('//')[1];
let asset = state.data.assets.find(a => a.uuid === uuid);
......@@ -449,28 +469,17 @@ export const projectStore = {
let _img = new Image();
_img.src = _url;
_img.onload = function () {
_props.width = _img.width;
_props.height = _img.height;
commit('modifyActiveView', {
properties: {
width: _img.width,
height: _img.height
}
properties: _props
});
}
}
}
let finalProps = _.merge({}, _.cloneDeep(state.activeComponent.properties), props);
// 属性冲突&属性关联计算
// if (finalProps.left && finalProps.right) {
// left right 同时存在,计算其宽度
// }
commit('modifyActiveView', {
properties: props
properties: _props
})
},
/**
......
......@@ -151,24 +151,24 @@ function inheritProps(props, parent, onlyOpera) {
}
let rule = propsComputeRules[key];
// 加法
if (rule === 'add') {
if (props[key] === null || props[key] === undefined) {
props[key] = 0;
}
props[key] += _pValue;
}
// if (rule === 'add') {
// if (props[key] === null || props[key] === undefined) {
// props[key] = 0;
// }
// props[key] += _pValue;
// }
// 乘法
if (rule === 'multi') {
if (props[key] === null || props[key] === undefined) {
props[key] = 1;
}
props[key] *= _pValue;
}
// if (rule === 'multi') {
// if (props[key] === null || props[key] === undefined) {
// props[key] = 1;
// }
// props[key] *= _pValue;
// }
// 可见,特殊处理
// 节点和父节点的visible只要有一个是false,值就是false,否则为true
if (rule === 'visible') {
props[key] = !props[key] || !_pValue ? false : true;
}
// if (rule === 'visible') {
// props[key] = !props[key] || !_pValue ? false : true;
// }
});
}
......
......@@ -2,14 +2,14 @@
<template>
<div class="zero-draw-panel-container" >
<div class="zero-components-container" >
<div
<!-- <div
:key="item.uuid"
v-for="item in componentList"
>
<wrap :component-data="item"/>
</div>
<!-- <views-tree :views="views"></views-tree> -->
<template v-if="!!this.activeComponentId">
</div> -->
<views-tree :views="views"></views-tree>
<!-- <template v-if="!!this.activeComponentId">
<vue-draggable-resizable
:prevent-deactivation="true"
class-name="db-draggable"
......@@ -26,109 +26,109 @@
@deactivated="handleDeactivated"
>
</vue-draggable-resizable>
</template>
</template> -->
</div>
</div>
</template>
<script>
import { mapState, mapGetters } from 'vuex';
import wrap from './wrap';
import { mapGetters } from 'vuex';
// import wrap from './wrap';
import viewsTree from './viewsTree';
import { styles } from '../../../utils/common';
import properties from '../../../utils/properties';
import VueDraggableResizable from 'vue-draggable-resizable';
// import { styles } from '../../../utils/common';
// import properties from '../../../utils/properties';
// import VueDraggableResizable from 'vue-draggable-resizable';
export default {
components: { wrap, VueDraggableResizable, viewsTree },
components: { viewsTree },
methods: {
handleDeactivated() {
// this.$store.dispatch('changeEditaleStatus', false);
},
handleResize(x, y, w, h) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponentCopy.properties;
// handleDeactivated() {
// // this.$store.dispatch('changeEditaleStatus', false);
// },
// handleResize(x, y, w, h) {
// if (!this.active || !this.activeComponentId) {
// return false;
// }
// let _prop = this.activeComponentCopy.properties;
if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
this.$store.dispatch('modifyCopyProperties', {
x: x,
y: y,
width: w,
height: h
});
// console.log('handleResize', x, y, w, h);
}
},
// if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
// this.$store.dispatch('modifyCopyProperties', {
// x: x,
// y: y,
// width: w,
// height: h
// });
// // console.log('handleResize', x, y, w, h);
// }
// },
handleDragging(x, y) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponentCopy.properties;
// handleDragging(x, y) {
// if (!this.active || !this.activeComponentId) {
// return false;
// }
// let _prop = this.activeComponentCopy.properties;
if (_prop.x !== x || _prop.y !== y) {
this.$store.dispatch('modifyCopyProperties', {
x: x,
y: y
});
// console.log('handleDragging', x, y);
}
},
handleResizeStop(x, y, w, h) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponent.properties;
// if (_prop.x !== x || _prop.y !== y) {
// this.$store.dispatch('modifyCopyProperties', {
// x: x,
// y: y
// });
// // console.log('handleDragging', x, y);
// }
// },
// handleResizeStop(x, y, w, h) {
// if (!this.active || !this.activeComponentId) {
// return false;
// }
// let _prop = this.activeComponent.properties;
if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
this.$store.dispatch('modifyProperties', {
x: x,
y: y,
width: w,
height: h
});
}
},
handleDragStop(x, y) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponent.properties;
// if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
// this.$store.dispatch('modifyProperties', {
// x: x,
// y: y,
// width: w,
// height: h
// });
// }
// },
// handleDragStop(x, y) {
// if (!this.active || !this.activeComponentId) {
// return false;
// }
// let _prop = this.activeComponent.properties;
if (_prop.x !== x || _prop.y !== y) {
this.$store.dispatch('modifyProperties', {
x: x,
y: y
});
}
}
// if (_prop.x !== x || _prop.y !== y) {
// this.$store.dispatch('modifyProperties', {
// x: x,
// y: y
// });
// }
// }
},
computed: {
...mapState(['project']),
...mapGetters(['activeComponent', 'activeComponentCopy', 'views', 'componentList', 'activeComponentId']),
active() {
return !!this.activeComponentId;
// return this.activeComponentId === (this.activeComponent || {}).uuid;
},
styleObject() {
return styles.getComponentStyle(this.activeComponentCopy, this.project, this.componentList, true);
},
position() {
let _props = this.activeComponentCopy.properties || {};
const _node = properties.node;
// console.log('********', _props);
let result = {
x: _props.x || _node.x.value,
y: _props.y || _node.y.value,
w: _props.width || _node.width.value,
h: _props.height || _node.height.value
};
// console.log('####position', result);
// ...mapState(['project']),
...mapGetters(['views']),
// active() {
// return !!this.activeComponentId;
// // return this.activeComponentId === (this.activeComponent || {}).uuid;
// },
// styleObject() {
// return styles.getComponentStyle(this.activeComponentCopy, this.project, this.componentList, true);
// },
// position() {
// let _props = this.activeComponentCopy.properties || {};
// const _node = properties.node;
// // console.log('********', _props);
// let result = {
// x: _props.x || _node.x.value,
// y: _props.y || _node.y.value,
// w: _props.width || _node.width.value,
// h: _props.height || _node.height.value
// };
// // console.log('####position', result);
return result;
}
// return result;
// }
}
};
</script>
......
......@@ -5,6 +5,23 @@
<views-tree :views="view.children"></views-tree>
</template>
</custom-node>
<vue-draggable-resizable
v-if="hasDrag"
:prevent-deactivation="true"
class-name="db-draggable"
:min-width="1"
:min-height="1"
:z="2"
:active="true"
:style="dragStyleObject"
v-bind="position"
@dragging="handleDragging"
@dragstop="handleDragStop"
@resizing="handleResize"
@resizestop="handleResizeStop"
@deactivated="handleDeactivated"
>
</vue-draggable-resizable>
</div>
</template>
......@@ -12,6 +29,8 @@
import { mapState, mapGetters } from 'vuex';
import { styles } from '../../../utils/common';
import customNode from '../../../components/customElement/node/index.vue';
import properties from '../../../utils/properties';
import VueDraggableResizable from 'vue-draggable-resizable';
export default {
name: 'viewsTree',
......@@ -22,11 +41,38 @@ export default {
}
},
components: {
VueDraggableResizable,
'custom-node': customNode
},
computed: {
...mapState(['project']),
...mapGetters(['activeComponentCopy', 'componentList'])
...mapGetters(['activeComponent', 'activeComponentCopy', 'componentList', 'activeComponentId']),
active() {
return !!this.activeComponentId;
},
dragStyleObject() {
return styles.getComponentStyle(this.activeComponentCopy, this.project, this.componentList, true);
},
position() {
let _props = this.activeComponentCopy.properties || {};
const _node = properties.node;
// console.log('********', _props);
let result = {
x: _props.x || _node.x.value,
y: _props.y || _node.y.value,
w: _props.width || _node.width.value,
h: _props.height || _node.height.value
};
// console.log('####position', result);
return result;
},
hasDrag() {
let _ids = this.views.map(v => v.uuid);
// console.log('_ids', _ids);
// console.log('activeComponentId', this.activeComponentId, _ids.indexOf(this.activeComponentId));
return this.activeComponentId && _ids.indexOf(this.activeComponentId) > -1 ? true : false;
}
},
methods: {
styleObject(view) {
......@@ -37,6 +83,66 @@ export default {
result = styles.getComponentStyle(view, this.project, this.componentList);
}
return result;
},
handleDeactivated() {
// this.$store.dispatch('changeEditaleStatus', false);
},
handleResize(x, y, w, h) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponentCopy.properties;
if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
this.$store.dispatch('modifyCopyProperties', {
x: x,
y: y,
width: w,
height: h
});
}
},
handleDragging(x, y) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponentCopy.properties;
if (_prop.x !== x || _prop.y !== y) {
this.$store.dispatch('modifyCopyProperties', {
x: x,
y: y
});
}
},
handleResizeStop(x, y, w, h) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponent.properties;
if (_prop.x !== x || _prop.y !== y || _prop.width !== w || _prop.height !== h) {
this.$store.dispatch('modifyProperties', {
x: x,
y: y,
width: w,
height: h
});
}
},
handleDragStop(x, y) {
if (!this.active || !this.activeComponentId) {
return false;
}
let _prop = this.activeComponent.properties;
if (_prop.x !== x || _prop.y !== y) {
this.$store.dispatch('modifyProperties', {
x: x,
y: y
});
}
}
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment