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

feat: 增加中间编辑区点击节点选中事件,并联动展开左侧节点树

parent 291c0f5a
<template> <template>
<div :style="customStyle" class="zero-custom-cmp zero-custom-node"> <div :style="customStyle" @click.self.stop="clickViewHandle(view)" class="zero-custom-cmp zero-custom-node">
<p class="custom-node-html" v-if="selfText">{{selfText}}</p> <p class="custom-node-html" v-if="selfText">{{selfText}}</p>
<slot></slot> <slot></slot>
</div> </div>
...@@ -30,12 +30,21 @@ export default { ...@@ -30,12 +30,21 @@ export default {
properties: { properties: {
type: Object, type: Object,
default: () => {} default: () => {}
},
view: {
type: Object,
default: () => {}
} }
}, },
computed: { computed: {
selfText() { selfText() {
return this.properties ? this.properties.text || '' : ''; return this.properties ? this.properties.text || '' : '';
} }
},
methods: {
clickViewHandle(data) {
this.$store.dispatch('activeComponent', {data, fromPlayground: true});
}
} }
}; };
</script> </script>
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
*/ */
import Vue from "vue"; import Vue from "vue";
import JSZip from "jszip"; import JSZip from "jszip";
import {projectApi} from "../../api"; import { projectApi } from "../../api";
import path from "path"; import path from "path";
import generateUUID from "uuid/v4"; import generateUUID from "uuid/v4";
import {getCmpProps, flattenViews, getCmpByUUID} from '../../utils/common'; import { getCmpProps, flattenViews, getCmpByUUID } from '../../utils/common';
import {clonePureObj, saveAs} from "../../utils"; import { clonePureObj, saveAs } from "../../utils";
import {template} from "../../template"; import { template } from "../../template";
import {importView, uploadFile} from "../../api/project"; import { importView, uploadFile } from "../../api/project";
import events from "@/global-events"; import events from "@/global-events";
const defaultOptions = { const defaultOptions = {
...@@ -23,8 +23,8 @@ const defaultOptions = { ...@@ -23,8 +23,8 @@ const defaultOptions = {
rendererType: 'webgl', rendererType: 'webgl',
tpl: template, tpl: template,
env: [ env: [
{name: 'appID', value: ''}, { name: 'appID', value: '' },
{name: 'projectID', value: ''}, { name: 'projectID', value: '' },
], ],
}; };
...@@ -61,14 +61,14 @@ export const projectStore = { ...@@ -61,14 +61,14 @@ export const projectStore = {
state.dirty = dirty; state.dirty = dirty;
}, },
updateProject(state, project) { updateProject(state, project) {
const {id, name, creator, data} = project; const { id, name, creator, data } = project;
state.id = id; state.id = id;
state.name = name; state.name = name;
state.creator = creator; state.creator = creator;
const localData = state.data; const localData = state.data;
if (data) { if (data) {
const {views, assets, dataMapping, processes, options, customs,} = JSON.parse(data); const { views, assets, dataMapping, processes, options, customs, } = JSON.parse(data);
Vue.set(localData, 'options', options || getDefaultOptions()); Vue.set(localData, 'options', options || getDefaultOptions());
Vue.set(localData, 'views', views || []); Vue.set(localData, 'views', views || []);
...@@ -255,7 +255,7 @@ export const projectStore = { ...@@ -255,7 +255,7 @@ export const projectStore = {
modifyProject(state) { modifyProject(state) {
}, },
addNode(state, {node, name, type}) { addNode(state, { node, name, type }) {
const child = { const child = {
name, name,
type, type,
...@@ -275,19 +275,19 @@ export const projectStore = { ...@@ -275,19 +275,19 @@ export const projectStore = {
importView(state, view) { importView(state, view) {
state.data.views.push(view); state.data.views.push(view);
}, },
deleteNode(state, {node, parentNode}) { deleteNode(state, { node, parentNode }) {
const parentChildren = parentNode.children || parentNode; const parentChildren = parentNode.children || parentNode;
const index = parentChildren.indexOf(node); const index = parentChildren.indexOf(node);
parentChildren.splice(index, 1); parentChildren.splice(index, 1);
}, },
copyNode(state, {node, parentNode}) { copyNode(state, { node, parentNode }) {
// const parentChildren = parentNode.children || parentNode; // const parentChildren = parentNode.children || parentNode;
// const index = parentChildren.indexOf(node); // const index = parentChildren.indexOf(node);
// parentNode.children.push(node); // parentNode.children.push(node);
// parentChildren.push(parentChildren[index]); // parentChildren.push(parentChildren[index]);
const child = { const child = {
name:node.name, name: node.name,
type:node.type, type: node.type,
properties: node.properties, properties: node.properties,
events: node.events, events: node.events,
uuid: generateUUID(), uuid: generateUUID(),
...@@ -304,7 +304,7 @@ export const projectStore = { ...@@ -304,7 +304,7 @@ export const projectStore = {
importAssets(state, assets) { importAssets(state, assets) {
state.data.assets.push(...assets); state.data.assets.push(...assets);
}, },
addAsset(state, {url, file}) { addAsset(state, { url, file }) {
const ext = path.extname(file.name); const ext = path.extname(file.name);
state.data.assets.push({ state.data.assets.push({
name: path.basename(file.name, ext), name: path.basename(file.name, ext),
...@@ -314,7 +314,7 @@ export const projectStore = { ...@@ -314,7 +314,7 @@ export const projectStore = {
}) })
}, },
deleteAsset(state, uuid) { deleteAsset(state, uuid) {
const {assets} = state.data; const { assets } = state.data;
for (let i = 0, li = assets.length; i < li; i++) { for (let i = 0, li = assets.length; i < li; i++) {
const asset = state.data.assets[i]; const asset = state.data.assets[i];
if (asset.uuid === uuid) { if (asset.uuid === uuid) {
...@@ -324,7 +324,7 @@ export const projectStore = { ...@@ -324,7 +324,7 @@ export const projectStore = {
} }
}, },
deleteAllAssets(state) { deleteAllAssets(state) {
const {assets} = state.data; const { assets } = state.data;
assets.splice(0); assets.splice(0);
}, },
modifyAsset(state, asset) { modifyAsset(state, asset) {
...@@ -378,7 +378,7 @@ export const projectStore = { ...@@ -378,7 +378,7 @@ export const projectStore = {
}, },
getters: { getters: {
project(state) { project(state) {
const {id, name, creator, data} = state; const { id, name, creator, data } = state;
return { return {
id, name, creator, id, name, creator,
data: JSON.stringify(data), data: JSON.stringify(data),
...@@ -443,17 +443,17 @@ export const projectStore = { ...@@ -443,17 +443,17 @@ export const projectStore = {
} }
}, },
actions: { actions: {
saveToLocal({getters, commit}) { saveToLocal({ getters, commit }) {
const {project} = getters; const { project } = getters;
localStorage.setItem('project-' + project.id, JSON.stringify(project)); localStorage.setItem('project-' + project.id, JSON.stringify(project));
commit('setDirty', true); commit('setDirty', true);
}, },
localVersionExist({commit}, projectID) { localVersionExist({ commit }, projectID) {
let json = localStorage.getItem('project-' + projectID); let json = localStorage.getItem('project-' + projectID);
return !!json; return !!json;
}, },
loadFromLocal({commit}, projectID) { loadFromLocal({ commit }, projectID) {
let json = localStorage.getItem('project-' + projectID); let json = localStorage.getItem('project-' + projectID);
if (json) { if (json) {
const project = JSON.parse(json); const project = JSON.parse(json);
...@@ -461,11 +461,11 @@ export const projectStore = { ...@@ -461,11 +461,11 @@ export const projectStore = {
commit('setDirty', true); commit('setDirty', true);
} }
}, },
deleteLocalVersion({state, commit}, projectID) { deleteLocalVersion({ state, commit }, projectID) {
localStorage.removeItem('project-' + projectID); localStorage.removeItem('project-' + projectID);
commit('setDirty', false); commit('setDirty', false);
}, },
async loadFromRemote({commit, dispatch}, projectID) { async loadFromRemote({ commit, dispatch }, projectID) {
const project = await projectApi.fetchOne(projectID); const project = await projectApi.fetchOne(projectID);
if (project) { if (project) {
dispatch('deleteLocalVersion', projectID); dispatch('deleteLocalVersion', projectID);
...@@ -474,11 +474,11 @@ export const projectStore = { ...@@ -474,11 +474,11 @@ export const projectStore = {
throw new Error('Project does not exist') throw new Error('Project does not exist')
} }
}, },
async saveToRemote({state, dispatch, getters}) { async saveToRemote({ state, dispatch, getters }) {
await projectApi.saveOne(getters.project); await projectApi.saveOne(getters.project);
dispatch('deleteLocalVersion', state.id); dispatch('deleteLocalVersion', state.id);
}, },
async updateProject({commit}, projectID) { async updateProject({ commit }, projectID) {
const project = await projectApi.getData(projectID); const project = await projectApi.getData(projectID);
commit('updateProject', project); commit('updateProject', project);
}, },
...@@ -496,18 +496,21 @@ export const projectStore = { ...@@ -496,18 +496,21 @@ export const projectStore = {
return getTopView(node.parent); return getTopView(node.parent);
} }
}; };
if (!data.fromPlayground) {
// 点击视图区域选中节点
// 则需要切换当前节点所在的最顶层视图
let _view = getTopView(data.node); let _view = getTopView(data.node);
if (_view && _view.data) { if (_view && _view.data) {
context.state.activeViews = _view.data.uuid; context.state.activeViews = _view.data.uuid;
} }
}
context.commit('activeComponent', data.data); context.commit('activeComponent', data.data);
}, },
/** /**
* 修改属性 * 修改属性
*/ */
modifyProperties({commit, state, getters}, props) { modifyProperties({ commit, state, getters }, props) {
// debugger; // debugger;
// 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度 // 如果当前修改的是“来源”属性,节点又没有高度宽度,则取图片的高度宽度
let _props = _.cloneDeep(state.activeComponent.properties); let _props = _.cloneDeep(state.activeComponent.properties);
...@@ -546,13 +549,13 @@ export const projectStore = { ...@@ -546,13 +549,13 @@ export const projectStore = {
* @param {*} param0 * @param {*} param0
* @param {*} props * @param {*} props
*/ */
modifyCopyProperties({commit}, props) { modifyCopyProperties({ commit }, props) {
commit('modifyCopyProperties', props) commit('modifyCopyProperties', props)
}, },
/** /**
* 修改当前选中的节点 * 修改当前选中的节点
*/ */
modifyActiveView({commit}, view) { modifyActiveView({ commit }, view) {
commit('modifyActiveView', view) commit('modifyActiveView', view)
}, },
...@@ -561,7 +564,7 @@ export const projectStore = { ...@@ -561,7 +564,7 @@ export const projectStore = {
* @param {*} param0 * @param {*} param0
* @param {*} data * @param {*} data
*/ */
addNodeScript({commit, state}, script) { addNodeScript({ commit, state }, script) {
let _scripts = _.cloneDeep(state.activeComponent.scripts || []); let _scripts = _.cloneDeep(state.activeComponent.scripts || []);
_scripts.push({ _scripts.push({
script: script, script: script,
...@@ -571,8 +574,8 @@ export const projectStore = { ...@@ -571,8 +574,8 @@ export const projectStore = {
scripts: _scripts scripts: _scripts
}) })
}, },
async importView({commit}, {file, action}) { async importView({ commit }, { file, action }) {
const {view, assets} = await importView(file); const { view, assets } = await importView(file);
switch (action) { switch (action) {
case 0: //单视图 case 0: //单视图
view.name = file.name.substring(0, file.name.lastIndexOf('.')); view.name = file.name.substring(0, file.name.lastIndexOf('.'));
...@@ -586,14 +589,14 @@ export const projectStore = { ...@@ -586,14 +589,14 @@ export const projectStore = {
} }
commit('importAssets', assets); commit('importAssets', assets);
}, },
exportView({state}, view) { exportView({ state }, view) {
let zip = new JSZip(); let zip = new JSZip();
zip.file('view.json', JSON.stringify(view)); zip.file('view.json', JSON.stringify(view));
zip.generateAsync({type: "blob"}).then(function (content) { zip.generateAsync({ type: "blob" }).then(function (content) {
saveAs(content, `view-${view.name}.zrv`); saveAs(content, `view-${view.name}.zrv`);
}); });
}, },
async uploadFiles({commit}, files) { async uploadFiles({ commit }, files) {
const failedList = []; const failedList = [];
let ps = []; let ps = [];
for (let file of files) { for (let file of files) {
...@@ -607,8 +610,8 @@ export const projectStore = { ...@@ -607,8 +610,8 @@ export const projectStore = {
} }
const result = await Promise.all(ps); const result = await Promise.all(ps);
for (let item of result) { for (let item of result) {
const {url, __originFile} = item; const { url, __originFile } = item;
commit('addAsset', {url, file: __originFile}); commit('addAsset', { url, file: __originFile });
} }
/*for (let file of files) { /*for (let file of files) {
try { try {
...@@ -621,7 +624,7 @@ export const projectStore = { ...@@ -621,7 +624,7 @@ export const projectStore = {
}*/ }*/
return failedList; return failedList;
}, },
async packProject({state}, debug) { async packProject({ state }, debug) {
const result = await projectApi.pack(state.id, debug); const result = await projectApi.pack(state.id, debug);
console.log(result); console.log(result);
return result; return result;
......
...@@ -17,7 +17,10 @@ ...@@ -17,7 +17,10 @@
:data="views" :data="views"
:props="defaultProps" :props="defaultProps"
:expand-on-click-node="false" :expand-on-click-node="false"
:default-expanded-keys="expandedKeys"
draggable draggable
ref="tree"
node-key="uuid"
highlight-current highlight-current
:default-expand-all="false" :default-expand-all="false"
@node-click="handleNodeClick" @node-click="handleNodeClick"
...@@ -54,7 +57,7 @@ ...@@ -54,7 +57,7 @@
</template> </template>
<script> <script>
import {mapState, mapMutations, mapActions} from 'vuex'; import {mapState, mapMutations, mapActions, mapGetters} from 'vuex';
import Pane from '../../components/Pane'; import Pane from '../../components/Pane';
import {selectFile} from "../../utils"; import {selectFile} from "../../utils";
import events from "../../global-events"; import events from "../../global-events";
...@@ -71,13 +74,22 @@ ...@@ -71,13 +74,22 @@
uploadHeaders: { uploadHeaders: {
authorization: 'Bearer ' + window['zeroing_token'], authorization: 'Bearer ' + window['zeroing_token'],
}, },
expandedKeys: []
}; };
}, },
computed: { computed: {
...mapGetters(['activeComponentId']),
...mapState({ ...mapState({
views: state => state.project.data.views views: state => state.project.data.views
}) })
}, },
watch: {
activeComponentId: function(val) {
this.$refs.tree.setCheckedKeys([val]); // 设置选中节点
this.$refs.tree.setCurrentKey(val); // 设置高亮节点
this.expandedKeys = [val]; // 展开对应的节点
}
},
methods: { methods: {
allowDrag(draggingNode) { allowDrag(draggingNode) {
return draggingNode.parent.parent; return draggingNode.parent.parent;
......
<template> <template>
<div class="views-tree"> <div class="views-tree">
<custom-node v-for="view in views" :key="view.uuid" :custom-style="styleObject(view)" :properties="view.properties"> <custom-node v-for="view in views" :key="view.uuid" :view="view" :custom-style="styleObject(view)" :properties="view.properties">
<template v-if="view.children"> <template v-if="view.children">
<views-tree :views="view.children"></views-tree> <views-tree :views="view.children"></views-tree>
</template> </template>
......
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