java和vue实现拖拽可视化_可视化拖拽页面编辑器 一__Vue.js
主题列表: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 () => (
{(dataModel.value?.blocks || []).map((block, index: number) => (
))}
);
},
});最终效果
画布会根据我们定义的editorData对象,来进行展示,container来描述画布的大小,block来描述在画布上的每个组件
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者: Miller
原文链接:https://juejin.im/post/6925976869334417421
java和vue实现拖拽可视化_可视化拖拽页面编辑器 一__Vue.js相关推荐
- 数据可视化 信息可视化_可视化哲学的黎明
数据可视化 信息可视化 Note: this is the foreword of the book Data Visualization in Society (Amsterdam Universi ...
- 数据可视化 信息可视化_可视化数据以帮助清理数据
数据可视化 信息可视化 The role of a data scientists involves retrieving hidden relationships between massive a ...
- 数据可视化 信息可视化_可视化数据操作数据可视化与纪录片的共同点
数据可视化 信息可视化 Data visualization is a great way to celebrate our favorite pieces of art as well as rev ...
- tkinter的可视化拖拽工具_可视化越做越丑?这五个高级图表效果实现流程分享给你...
今天我们来说一说数据可视化,想必很多人在入门数据分析之后,就会经常进行可视化的工作,所谓一图胜千言,图表用的好,真的是会事半功倍的.但现实情况下,很多人遇到的问题是: 你做的图表太丑了?你做的图表到底 ...
- java cms 拖拽布局_鼠标拖拽就能轻松建站 We7 CMS评测
We7 CMS是由西部动力推出的一套采用C#开发的,基于.net2.0,可以运行于Oracle.SQLite.Sqlserver.MySQL.Access等数据库之上的网站内容管理系统软件(Conte ...
- java 可视化_可视化Java 9模块关系
java 可视化 正如我在之前的文章中所述 ,我已经在Java 9 + Jigsaw构建上运行Eclipse Neon了一段时间,并且没有任何问题. 我在周末花了几个小时来修改一些模块化工具的想法. ...
- Java和vue实现音乐播放器_躁!DJ 风格 Java 桌面音乐播放器
本文适合有 Java 基础知识的人群,跟着本文可学习和运行 Java 版桌面 DJ 音乐播放器. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列 ...
- 百度指数可视化_可视化指数
百度指数可视化 Abstract:– Analysis of the visual representations of exponentials.– Proposals to solve curre ...
- nba球员数据分析和可视化_可视化NBA球员统计
nba球员数据分析和可视化 I haven't written a post in a while. I had a lot to do for university and my hobbies l ...
- python医学图像可视化_可视化医学图像CT
DICOM格式 Digital Imaging and Communications in Medicine (DICOM)是医学标准格式的医学图像 2加载第三方包 IS_LOCAL = False ...
最新文章
- NodeMCU快速上云集锦
- Linux内核探讨-- 第四章
- Android中Activity的四种启动模式
- 各路券商会盟互联网金融 敢问路在何方
- 用户管理界面开源代码_某教师培训信息管理系统渗透思路分享
- linux查进程内存问题,关于linux下内存问题排查的工具
- Linux常用文件拷贝方式:scp,rsync,expect
- 一键伪装成 Windows 10:Kali Linux 2019.4 版本推出 “Undercover” 模式
- 关于hibernate插入数据时的乱码问题
- python用户画像_Python爬虫实践之:简书用户画像
- 【R语言报错解决】—存在非数值型变量,Error in c_max * c_min : non-numeric argument to binary operator,如何在数据导入后转为数值型变量?
- 百度排名规则及算法(百度内部资料)
- 九校联考-长沙市一中NOIP模拟Day1T2 跳房子(jump)
- 数据结构课程设计——逆波兰表达式的计算
- 第三十二讲:循环思想(项目三十二:输出小星星图案)
- android电量优化方法,Android性能优化——电池使用优化
- 安装python卡到不动了_pip卡住不动的解决方案
- 00后大学生,学微积,用手机,从味同嚼蜡到喜闻乐见
- 【信息资源管理】第一章:信息资源管理基础
- 红米android4.4.2,【图片】红米2三网通刷CyanogenMod CM11 Android 4.4.4_红米2吧_百度贴吧...