Commit 3a988bf9 authored by 张晨辰's avatar 张晨辰

feat: 行为编辑

parent 0fcc4e27
......@@ -5,7 +5,7 @@
width="auto"
:content="url"
>
<img v-if="url" :src="url" alt="" />
<img style="max-width: 200px;" v-if="url" :src="url" alt="" />
<el-input v-model="swvalue" slot="reference" @drop.native="drop" @dragover.native="dragOver"></el-input>
</el-popover>
</template>
......
......@@ -3,9 +3,7 @@
*/
import Vue from "vue";
import JSZip from "jszip";
import { projectApi } from "../../api";
// import { compoleteComponentData } from '../../utils/compoleteCmpData';
import path from "path";
import generateUUID from "uuid/v4";
import { getCmpProps, flattenViews, getCmpByUUID } from '../../utils/common';
......@@ -50,7 +48,6 @@ export const projectStore = {
Vue.set(localData, 'assets', []);
Vue.set(localData, 'dataMapping', []);
}
// compoleteComponentData(state.data.views);
},
/**
* 激活组件
......@@ -58,11 +55,9 @@ export const projectStore = {
* @param {*} id
*/
activeComponent(state, item) {
// debugger;
if (item !== state.activeComponent) {
state.activeComponent = item || state.activeComponent;
state.activeComponent.properties = state.activeComponent.properties || {};
console.log('mutations activeComponent', state);
}
},
/**
......@@ -77,11 +72,14 @@ export const projectStore = {
let _prop = _.cloneDeep(state.activeComponent.properties || {});
if (state.operateStack.length) {
// state.operateStack.shift();
if (state.stackIndex !== 0) {
// 如果操作栈index有值,说明之前做过撤销/重做
// 则把操作index之后的数据都丢弃
state.operateStack = state.operateStack.slice(state.stackIndex);
}
} else {
// 如果操作栈中是空的,说明从来没有操作
// 则在开始插入数据的时候,额外插入一条最原始的数据
state.operateStack.unshift({
uuid: state.activeComponent.uuid,
properties: _.cloneDeep(_prop)
......@@ -89,14 +87,16 @@ export const projectStore = {
}
state.stackIndex = 0; // 开始编辑的时候,重置操作栈的下标
_prop = Object.assign({}, _prop, props);
// 在操作栈中插入最新值
state.operateStack.unshift({
uuid: state.activeComponent.uuid,
properties: _.cloneDeep(_prop)
});
// 操作栈最大200
if (state.operateStack.length > 200) {
state.operateStack.pop();
}
Vue.set(state.activeComponent, 'properties', _prop);
console.log('operateStack', state.operateStack);
// console.log('modifyProperties', state.activeComponent);
},
/**
* 修改当前组件
......@@ -117,17 +117,14 @@ export const projectStore = {
delete prop[key];
}
});
console.log('new properties', cmpProps);
Vue.set(state.activeComponent, 'properties', cmpProps);
}
console.log('modifyComponent', state.activeComponent);
},
/**
* assets拖拽
* @param {*} data
*/
assetDragStart(state, data) {
console.log('assetDragStart', data);
state.dragUUID = data.uuid;
},
/**
......@@ -143,7 +140,6 @@ export const projectStore = {
// 如果uuid不一样,说明是不同节点的操作,需要把下标多移动一位
state.stackIndex += step;
}
console.log('undoRedo', state.stackIndex);
let _operate = state.operateStack[state.stackIndex];
if (_operate) {
let _cmp = getCmpByUUID(_operate.uuid, state.data.views);
......@@ -152,7 +148,15 @@ export const projectStore = {
}
}
},
modifyProject(state, ) {
/**
* 修改节点的events
* @param {*} state
* @param {*} event
*/
updateNodeEvent(state, event) {
state.activeComponent.events = _.assign(state.activeComponent.events, event)
},
modifyProject(state) {
},
addNode(state, { node, name, type }) {
......@@ -160,6 +164,7 @@ export const projectStore = {
name,
type,
properties: {},
events: {},
uuid: generateUUID(),
};
if (node) {
......@@ -265,7 +270,7 @@ export const projectStore = {
}
let result = flattenViews(_.cloneDeep(_view));
console.log('componentList', result);
// console.log('componentList', result);
return result;
}
},
......@@ -369,6 +374,13 @@ export const projectStore = {
commit('modifyComponent', data)
},
/**
* 编辑节点事件
*/
updateNodeEvent({ commit }, data) {
commit('updateNodeEvent', data)
},
exportView({ state }, view) {
let zip = new JSZip();
zip.file('view.json', JSON.stringify(view));
......
......@@ -7,7 +7,7 @@
line-height: 25px;
}
.zero-inspector-form {
.zero-inspector-props-form {
.el-input-number.el-input-number--mini, .el-select.el-select--mini {
width: 100%;
}
......
......@@ -256,7 +256,7 @@ export const styles = {
});
result += `background-position: center;background-size: 100% 100%;`
console.log('getComponentStyle', result);
// console.log('getComponentStyle', result);
return result;
}
}
......
export default ['click', 'touchstart', 'touchend', 'touchmove']
\ No newline at end of file
......@@ -2,25 +2,7 @@
<pane icon="el-icon-s-operation" :title="$t('panes.Inspector')">
<el-tabs v-model="tab" type="border-card" class="inspector-tabs">
<el-tab-pane label="Props" name="properties">
<div class="zero-inspector-form">
<el-form ref="form" size="mini" v-if="activeComponent.uuid" :model="form" label-width="80px">
<el-divider content-position="left">配置</el-divider>
<el-form-item label="名称">
<el-input v-model="form.name" @input="v => handleChange('name', v)"></el-input>
</el-form-item>
<el-form-item label="类型">
<el-select v-model="form.type" @change="v => handleChange('type', v)" placeholder="请选择类型">
<el-option v-for="cmp in componentsMap" :key="cmp.value" :label="cmp.label" :value="cmp.value"></el-option>
</el-select>
</el-form-item>
<template v-for="(p, key) in cmpProps">
<el-form-item v-if="key !== 'groupName'" :id="activeComponent.uuid + '-' + key" :key="activeComponent.uuid + key" :label="p.title">
<!-- {{key}} -->
<dynamic-component :label="key" :item="p" :properties="activeComponent.properties"></dynamic-component>
</el-form-item>
</template>
</el-form>
</div>
<props-tab/>
</el-tab-pane>
<el-tab-pane label="Behavior" name="behavior">
<behavior-tab/>
......@@ -30,63 +12,20 @@
</template>
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
import Pane from '../../components/Pane';
import _ from 'lodash';
import { componentsMap, getCmpProps } from '../../utils/common';
import dynamicComponent from './components/dynamicComponent';
import BehaviorTab from "./Inspector/BehaviorTab";
import PropsTab from "./Inspector/PropsTab";
export default {
name: 'Inspector',
components: {BehaviorTab, Pane, 'dynamic-component': dynamicComponent },
components: {BehaviorTab, PropsTab, Pane},
data() {
return {
tab: 'properties',
componentsMap,
form: {
name: '',
type: '',
properties: {}
}
tab: 'properties'
};
},
computed: {
...mapGetters(['activeComponent', 'componentList']),
cmpProps: function() {
return getCmpProps(this.activeComponent.type);
}
},
watch: {
activeComponent: {
deep: true,
handler: function(val) {
this.form.name = val.name || '';
this.form.type = val.type || '';
this.form.properties = val.properties || {};
}
}
},
methods: {
handleChange(label, v) {
this.$store.dispatch('modifyComponent', {
label: label,
value: v
});
}
}
};
</script>
<style lang="scss">
.zero-inspector-form {
width: 100%;
padding-right: 10px;
.el-form-item--mini.el-form-item {
margin-bottom: 10px;
}
.el-divider__text {
background-color: #e9e9e9;
}
}
</style>
\ No newline at end of file
<template>
<div>
<el-button @click="showBehaviorEditor">行为编辑器</el-button>
<behavior-editor-dialog ref="behaviorEditorDialog"></behavior-editor-dialog>
<div class="zero-inspector-behavior-form" v-if="activeComponent.uuid">
<el-form ref="form" size="mini" label-width="80px">
<div v-for="(evn, key) in eventsObj" :key="key">
<el-form-item label="触发事件:">
<div>{{key}}</div>
<div >
<el-tooltip content="是否单次触发" placement="top">
<el-switch v-model="evn.once" @change="v => handleOnceChange(key, v)"></el-switch>
</el-tooltip>
<el-tooltip content="行为编辑" placement="top" style="margin-left: 20px;">
<el-button size="mini" @click="showBehaviorEditor(evn, key)">
行为编辑
<i v-if="evn.behaviors && evn.behaviors.length" class="el-icon-check el-icon--right"></i>
</el-button>
</el-tooltip>
</div>
</el-form-item>
</div>
</el-form>
<behavior-editor-dialog :behaviors="behaviors" @change="v => handleBehaviorsChange(v)" ref="behaviorEditorDialog"></behavior-editor-dialog>
</div>
</template>
<script>
import BehaviorEditorDialog from "../dialogs/BehaviorEditorDialog";
export default {
name: "BehaviorTab",
components: {BehaviorEditorDialog},
import { mapGetters } from 'vuex';
import _ from 'lodash';
import events from '../../../utils/events';
import BehaviorEditorDialog from '../dialogs/BehaviorEditorDialog';
export default {
name: 'BehaviorTab',
data() {
let eventsObj = {};
events.forEach(event => {
eventsObj[event] = {
once: false,
behaviors: []
};
});
return {
eventsObj,
behaviors: [],
currentEvent: ''
};
},
components: { BehaviorEditorDialog },
computed: {
...mapGetters(['activeComponent', 'componentList'])
},
methods: {
showBehaviorEditor() {
showBehaviorEditor(evn, key) {
this.currentEvent = key;
this.behaviors = evn.behaviors || [];
this.$refs.behaviorEditorDialog.show();
},
/**
* 当前选中组件发生变化时,更新eventsObj的数据
*/
updateEventsObj() {
let _events = this.activeComponent.events || {};
_.forIn(this.eventsObj, (value, key) => {
if (_events[key]) {
this.$set(this.eventsObj, key, _.cloneDeep(_events[key]));
} else {
value.once = false;
value.behaviors = [];
}
});
},
/**
* 是否只执行一次
*/
handleOnceChange(key, v) {
let _event = this.eventsObj[key];
// 如果没有behavior,once没有用处,则不执行
if (_event.behaviors && _event.behaviors.length) {
let event = {};
event[key] = {
once: v,
behaviors: _event.behaviors
};
this.$store.dispatch('updateNodeEvent', event);
}
},
/**
* 行为发生变化,同步数据
*/
handleBehaviorsChange(v) {
if (this.currentEvent && v && v.length) {
let event = {};
let currentEvent = this.eventsObj[this.currentEvent];
event[this.currentEvent] = Object.assign(currentEvent, { behaviors: v });
this.$store.dispatch('updateNodeEvent', event);
this.updateEventsObj();
}
}
},
watch: {
'activeComponent.uuid': function() {
this.updateEventsObj();
console.log('activeComponent.uuid change');
}
}
};
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div class="zero-inspector-props-form" v-if="activeComponent.uuid">
<el-collapse v-model="configColl">
<el-collapse-item title="配置" name="properties">
<el-form ref="form" size="mini" :model="form" label-width="80px">
<el-form-item label="名称">
<el-input v-model="form.name" @input="v => handleChange('name', v)"></el-input>
</el-form-item>
<el-form-item label="类型">
<el-select v-model="form.type" @change="v => handleChange('type', v)" placeholder="请选择类型">
<el-option v-for="cmp in componentsMap" :key="cmp.value" :label="cmp.label" :value="cmp.value"></el-option>
</el-select>
</el-form-item>
<template v-for="(p, key) in cmpProps">
<el-form-item v-if="key !== 'groupName'" :id="activeComponent.uuid + '-' + key" :key="activeComponent.uuid + key" :label="p.title">
<!-- {{key}} -->
<dynamic-component :label="key" :item="p" :properties="activeComponent.properties"></dynamic-component>
</el-form-item>
</template>
</el-form>
</el-collapse-item>
<el-collapse-item title="脚本" name="scripts">
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { componentsMap, getCmpProps } from '../../../utils/common';
import dynamicComponent from '../components/dynamicComponent';
export default {
name: 'PropsTab',
components: { 'dynamic-component': dynamicComponent },
data() {
return {
componentsMap,
form: {
name: '',
type: '',
properties: {}
},
configColl: ['properties']
};
},
computed: {
...mapGetters(['activeComponent', 'componentList']),
cmpProps: function() {
return getCmpProps(this.activeComponent.type);
}
},
watch: {
activeComponent: {
deep: true,
handler: function(val) {
this.form.name = val.name || '';
this.form.type = val.type || '';
this.form.properties = val.properties || {};
}
}
},
methods: {
handleChange(label, v) {
this.$store.dispatch('modifyComponent', {
label: label,
value: v
});
}
}
};
</script>
<style lang="scss">
.zero-inspector-props-form {
width: 100%;
padding-right: 10px;
.el-form-item--mini.el-form-item {
margin-bottom: 10px;
}
.el-divider__text {
background-color: #e9e9e9;
}
}
</style>
\ No newline at end of file
......@@ -55,7 +55,7 @@ export default {
width: w,
height: h
});
console.log('handleResize', x, y, w, h);
// console.log('handleResize', x, y, w, h);
}
},
......@@ -70,11 +70,11 @@ export default {
x: x,
y: y
});
console.log('handleDragging', x, y);
// console.log('handleDragging', x, y);
}
},
resizeStop(x, y, w, h) {
console.log('resizeStop', x, y, w, h);
// console.log('resizeStop', x, y, w, h);
}
},
computed: {
......@@ -97,7 +97,7 @@ export default {
w: _props.width || _node.width.value,
h: _props.height || _node.height.value
};
console.log('####position', result);
// console.log('####position', result);
return result;
}
......
......@@ -31,6 +31,7 @@
},
onSave() {
this.visible = false;
this.$emit('change')
},
onOpened() {
this.$refs.behaviorEditor.measure();
......
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