主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow, v-green, vue-pro, healer-readable, mk-cute, jzman, geek-black, awesome-green, qklhk-chocolate

theme: juejin

highlight:

前端技术日益发展,组件化日益成熟,作为一个前端,每天的工作就是用组件堆砌页面,有没有一种方式可以像CocosCreator,通过组件+脚本绑定的方式来实现我们的页面和功能,今天我们就来实现一个提高生产力的工具 可视化拖拽页面编辑器, 让产品和UI通过拖拽编辑页面,生产自己想要的页面。

技术框架采用Vue3 + Typescript + ElementPlus

每个章节下边都会贴出对应commit代码,方便大家对比学习

最终效果

实现功能:

主页面结构:左侧可选组件列表、中间容器画布、右侧编辑组件定义好的属性

从菜单拖拽组件到容器;

单选、多选;

容器内的组件可以拖拽移动位置;

组件拖拽调整宽高;

组件拖拽贴边,显示辅助线;

操作栏按钮与命令

撤销、重做;

导入、导出;

置顶、置底;

删除、清空;

组件绑定值;

根据组件标识,通过作用域插槽自定义某个组件的行为

预览地址

一、项目搭建与页面布局

通过vue-cli生成项目

vue create visual-editor-vue选择手动配置

选择配置如下:

选择vue3.x版本

这一步选y,使用jsx写组件,需要添加对应的babel插件

接下来我们来实现基本的左中右布局

左侧菜单栏放置组件列表

中间是画布和工具栏,用来编辑预览页面

右侧是我们选中某个组件后,显示的该组件的属性

第一部分代码:基本布局

二、数据结构设计与双向绑定实现

数据结构设计

定义数据结构如下

container 表示画布容器

blocks 表示放置在容器中的组件

每个block表示一个组件,包含了组件的类型位置、宽高、选中状态等信息

画布采用绝对定位,里面的元素通过top、left来确定位置

{

"container": {

"height": 500,

"width": 800

},

"blocks": [

{

"componentKey": "button",

"top": 102,

"left": 136,

"adjustPosition": false,

"focus": false,

"zIndex": 0,

"width": 0,

"height": 0

},

{

"componentKey": "input",

"top": 148,

"left": 358,

"adjustPosition": false,

"focus": false,

"zIndex": 0,

"width": 244,

"height": 0

}

]

}

数据双向绑定实现

组件采用vue3中的jsx语法编写,需要实现数据双向绑定机制,useModel就是用来处理数据双向绑定的

import { computed, defineComponent, ref, watch } from "vue";

// 用jsx封装组件的时候,实现双向数据绑定

export function useModel(getter: () => T, emitter: (val: T) => void) {

const state = ref(getter()) as { value: T };

watch(getter, (val) => {

if (val !== state.value) {

state.value = val;

}

});

return {

get value() {

return state.value;

},

set value(val: T) {

if (state.value !== val) {

state.value = val;

emitter(val);

}

},

};

}

useModel用法

// modelValue 外部可以用v-model绑定

export const TestUseModel = defineComponent({

props: {

modelValue: { type: String },

},

emits: {

"update:modelValue": (val?: string) => true,

},

setup(props, ctx) {

const model = useModel(

() => props.modelValue,

(val) => ctx.emit("update:modelValue", val)

);

return () => (

自定义输入框

);

},

});

三、Block渲染

新建visual-editor-block的组件

block来表示在画布显示的组件元素

block先用文本来显示

import { computed, defineComponent, PropType } from "vue";

import { VisualEditorBlockData } from "./visual-editor.utils";

export const VisualEditorBlock = defineComponent({

props: {

block: {

type: Object as PropType,

},

},

setup(props) {

const styles = computed(() => ({

top: `${props.block?.top}px`,

left: `${props.block?.left}px`,

}));

return () => (

这是一条block

);

},

});将定义的数据用v-model传入editor

App.vue文件

import { defineComponent } from "vue";

import { VisualEditor } from "../src/packages/visual-editor";

export default defineComponent({

name: "App",

components: { VisualEditor },

data() {

return {

editorData: {

container: {

height: 500,

width: 800,

},

blocks: [

{ top: 100, left: 100 },

{ top: 200, left: 200 },

],

},

};

},

});

引入block组件,并进行渲染

visual-editor.tsx文件

import { computed, defineComponent, PropType } from "vue";

import { useModel } from "./utils/useModel";

import { VisualEditorBlock } from "./visual-editor-block";

import "./visual-editor.scss";

import { VisualEditorModelValue } from "./visual-editor.utils";

export const VisualEditor = defineComponent({

props: {

modelValue: {

type: Object as PropType,

},

},

emits: {

"update:modelValue": (val?: VisualEditorModelValue) => true,

},

setup(props, ctx) {

const dataModel = useModel(

() => props.modelValue,

(val) => ctx.emit("update:modelValue", val)

);

const containerStyles = computed(() => ({

width: `${props.modelValue?.container.width}px`,

height: `${props.modelValue?.container.height}px`,

}));

return () => (

menu
head
operator

{(dataModel.value?.blocks || []).map((block, index: number) => (

))}

);

},

});最终效果

画布会根据我们定义的editorData对象,来进行展示,container来描述画布的大小,block来描述在画布上的每个组件

版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作者: Miller

原文链接:https://juejin.im/post/6925976869334417421

java和vue实现拖拽可视化_可视化拖拽页面编辑器 一__Vue.js相关推荐

  1. 数据可视化 信息可视化_可视化哲学的黎明

    数据可视化 信息可视化 Note: this is the foreword of the book Data Visualization in Society (Amsterdam Universi ...

  2. 数据可视化 信息可视化_可视化数据以帮助清理数据

    数据可视化 信息可视化 The role of a data scientists involves retrieving hidden relationships between massive a ...

  3. 数据可视化 信息可视化_可视化数据操作数据可视化与纪录片的共同点

    数据可视化 信息可视化 Data visualization is a great way to celebrate our favorite pieces of art as well as rev ...

  4. tkinter的可视化拖拽工具_可视化越做越丑?这五个高级图表效果实现流程分享给你...

    今天我们来说一说数据可视化,想必很多人在入门数据分析之后,就会经常进行可视化的工作,所谓一图胜千言,图表用的好,真的是会事半功倍的.但现实情况下,很多人遇到的问题是: 你做的图表太丑了?你做的图表到底 ...

  5. java cms 拖拽布局_鼠标拖拽就能轻松建站 We7 CMS评测

    We7 CMS是由西部动力推出的一套采用C#开发的,基于.net2.0,可以运行于Oracle.SQLite.Sqlserver.MySQL.Access等数据库之上的网站内容管理系统软件(Conte ...

  6. java 可视化_可视化Java 9模块关系

    java 可视化 正如我在之前的文章中所述 ,我已经在Java 9 + Jigsaw构建上运行Eclipse Neon了一段时间,并且没有任何问题. 我在周末花了几个小时来修改一些模块化工具的想法. ...

  7. Java和vue实现音乐播放器_躁!DJ 风格 Java 桌面音乐播放器

    本文适合有 Java 基础知识的人群,跟着本文可学习和运行 Java 版桌面 DJ 音乐播放器. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列 ...

  8. 百度指数可视化_可视化指数

    百度指数可视化 Abstract:– Analysis of the visual representations of exponentials.– Proposals to solve curre ...

  9. nba球员数据分析和可视化_可视化NBA球员统计

    nba球员数据分析和可视化 I haven't written a post in a while. I had a lot to do for university and my hobbies l ...

  10. python医学图像可视化_可视化医学图像CT

    DICOM格式 Digital Imaging and Communications in Medicine (DICOM)是医学标准格式的医学图像 2加载第三方包 IS_LOCAL = False ...

最新文章

  1. NodeMCU快速上云集锦
  2. Linux内核探讨-- 第四章
  3. Android中Activity的四种启动模式
  4. 各路券商会盟互联网金融 敢问路在何方
  5. 用户管理界面开源代码_某教师培训信息管理系统渗透思路分享
  6. linux查进程内存问题,关于linux下内存问题排查的工具
  7. Linux常用文件拷贝方式:scp,rsync,expect
  8. 一键伪装成 Windows 10:Kali Linux 2019.4 版本推出 “Undercover” 模式
  9. 关于hibernate插入数据时的乱码问题
  10. python用户画像_Python爬虫实践之:简书用户画像
  11. 【R语言报错解决】—存在非数值型变量,Error in c_max * c_min : non-numeric argument to binary operator,如何在数据导入后转为数值型变量?
  12. 百度排名规则及算法(百度内部资料)
  13. 九校联考-长沙市一中NOIP模拟Day1T2 跳房子(jump)
  14. 数据结构课程设计——逆波兰表达式的计算
  15. 第三十二讲:循环思想(项目三十二:输出小星星图案)
  16. android电量优化方法,Android性能优化——电池使用优化
  17. 安装python卡到不动了_pip卡住不动的解决方案
  18. 00后大学生,学微积,用手机,从味同嚼蜡到喜闻乐见
  19. 【信息资源管理】第一章:信息资源管理基础
  20. 红米android4.4.2,【图片】红米2三网通刷CyanogenMod CM11 Android 4.4.4_红米2吧_百度贴吧...

热门文章

  1. ksz8863调试总线,
  2. ES 关于text和keyword两种类型数据搜索区别
  3. ico图片格式生成器
  4. 如何把PDF中的英文翻译成中文
  5. 信息系统项目管理师学习笔记13-项目合同管理
  6. 总方差公式(方差分解公式)证明
  7. 怎么屏蔽计算机集成声卡,win10系统主板集成声卡关闭的设置方案
  8. mysql 字段名 减号_MySQL表字段名不能包含减号
  9. 雷电模拟器 服务器无响应,雷电模拟器怎么用脚本长时间运行未响应win10
  10. 文件批量重命名怎么加下划线?