前端技术日益发展,组件化日益成熟,作为一个前端,每天的工作就是用组件堆砌页面,有没有一种方式可以像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 { 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来描述在画布上的每个组件

html 编辑器 拖动,可视化拖拽页面编辑器 一相关推荐

  1. vue拖动改变模板_可视化拖拽 UI 布局之拖拽篇

    前言:前段时间负责公司的运营管理后台项目,通过运营后台的PC端拖拽配置布局,达到App首页模板的动态UI界面配置,生成页面.趁着周末,整理一下当时所了解到的拖拽.文章会根据大家的反馈或者自己学习经验的 ...

  2. 移动端实现元素拖拽效果插件_基于自然流布局的可视化拖拽搭建平台设计方案...

    LowCode 是高效.高性能的拖拽式低代码开发平台. 也是笔者最近一直在研究的方向, 对于可视化搭建平台的实现方案笔者之前写过很多文章, 这里带大家探索一个新方向--基于自然流布局的可视化搭建平台. ...

  3. 可视化拖拽组件库一些技术要点原理分析(三)

    本文是可视化拖拽系列的第三篇,之前的两篇文章一共对 17 个功能点的技术原理进行了分析: 编辑器 自定义组件 拖拽 删除组件.调整图层层级 放大缩小 撤消.重做 组件属性设置 吸附 预览.保存代码 绑 ...

  4. 可视化拖拽组件库一些技术要点原理分析(二)

    本文是对<可视化拖拽组件库一些技术要点原理分析>[1]的补充.上一篇文章主要讲解了以下几个功能点: 1.编辑器2.自定义组件3.拖拽4.删除组件.调整图层层级5.放大缩小6.撤消.重做7. ...

  5. 基于自然流布局的可视化拖拽搭建平台设计方案

    LowCode 是高效.高性能的拖拽式低代码开发平台. 也是笔者最近一直在研究的方向, 对于可视化搭建平台的实现方案笔者之前写过很多文章, 这里带大家探索一个新方向--基于自然流布局的可视化搭建平台. ...

  6. 可视化拖拽组件库一些技术要点原理分析

    本文已获得原作者的独家授权,有想转载的朋友们可以在后台联系我申请开白哦! PS:欢迎掘友们向我投稿哦,被采用的文章还可以送你掘金精美周边! 本文主要对以下技术要点进行分析: 编辑器 自定义组件 拖拽 ...

  7. vue可视化拖拽生成工具_vdesjs: 基于vue的可视化拖拽,代码生成工具。提升前端开发效率,或者集成至项目作为在线拖拽工具。(持续迭代升级中)...

    vdesjs 介绍 vdesjs是一款基于vue技术栈,可视化拖拽,代码生成工具.我们提供详细的文档来帮助您理解我们工具的实现原理,并且您可以方便的基于vdesjs来扩展您自己的代码生成组件. 技术选 ...

  8. WordPress可视化拖拽自助建站主题The7 V10.0.0

    简介: WordPress可视化拖拽自助建站主题The7 V10.0.0 前端Html5+css3响应式,后台PHP,数据库mysql主机要求:支持php+mysql 汉化程度:后台和所有插件95汉化 ...

  9. 可视化拖拽 UI 布局之拖拽篇

    前言:前段时间负责公司的运营管理后台项目,通过运营后台的PC端拖拽配置布局,达到App首页模板的动态UI界面配置,生成页面.趁着周末,整理一下当时所了解到的拖拽.文章会根据大家的反馈或者自己学习经验的 ...

  10. 【大屏项目】SpringBoot + Vue 实现的可视化拖拽编辑的

    简介 大屏设计(AJ-Report)是一个可视化拖拽编辑的全开源项目,直观,酷炫,具有科技感的图表工具.内置的基础功能包括数据源,数据集,报表管理. 多数据源支持,内置mysql.elasticsea ...

最新文章

  1. inline函数返回值_C++知识补充-指针,const,函数指针,指针数组,运算符重载
  2. 智源青年科学家林乾:揭开人工智能的黑匣,从解答最基本的问题开始
  3. 在线教育这条取经路,有道词典何时能修成正果?
  4. android 活动说明,Android – 如何发送GCM推送通知以及要加载哪些活动的说明?
  5. IOS-C语言小练习02
  6. 导出文件_一招解决PDF文件导出图片
  7. 如何基于对话框的project基于改变BCG的
  8. python装饰器与闭包_Python:函数装饰器和闭包
  9. 助力Java初级程序员快速成长的营养书单
  10. PSV卡套 换卡工具 下载及使用
  11. PS后期一键调出紫色梦幻红外线照片效果
  12. 微信小程序 一键授权 给第三方平台代开发管理(一,创建第三方平台)
  13. 百度搜索算法全解析SEO课程笔记
  14. 沈劭劼居然还是大疆的....大疆真的可怕。大疆如果做一款室内无人机不分分钟秒杀其他。
  15. 【语义分割】Searching for Efficient Multi-Scale Architectures for Dense Image Prediction翻译
  16. 安卓大作业-字典App 可以查询汉字 可以玩成语接龙游戏
  17. 计算机教学音乐,计算机音乐的教学和应用研究
  18. 基于spec评论作品
  19. emqttd配置_EMQ(emqttd)的介绍和安装
  20. 体素转换为点云(VRN)

热门文章

  1. Linux 基础之基础网络ss命令
  2. 结构化程序设计方法和面向对象程序设计方法的区别
  3. 串口助手使用16进制发送数据
  4. ThoughtWorks笔试题大致解题思路总结
  5. 压缩照片大小——PPT实现
  6. python中bin的意思_python中bin函数的使用方法
  7. 电脑如何实现微信多开
  8. Racket编程指南——24 命令行工具和你的编辑器选择
  9. 什么是运行时应用程序自我保护(RASP)Runtime Application Self-Protection
  10. B代表哪一种氨基酸?B和b代表的氨基酸一样吗?