前端工程师是有极限的javascript
我从短暂的工做当中学到一件事......css
越是熬夜加班,就越会发现人类的能力是有极限的......前端
除非超越产品vue
我不加班了!!BOSSjava
拖拽生成h5页面,支持动画,模板,保存组件,第三方后台接入提交数据,欢迎体验git
基于vue搭建营销h5页面 易动 已上线,欢迎体验~~github
开源不易,给个Star吧~vuex
面对频繁变动的页面需求,面对客户像爱情同样的的需求(文字小一点,边距小一点),你是否是也曾经抓狂过,是否是也想说出内心的声音,我不想加班后端
因此对于特定的业务场景,例如活动页面,以及首页,这种常常须要修改的页面,彻底能够经过搭建进行完成,目前市场上搭建前端页面能够分为两类微信
实现方式是不少种的,本文提出的是一种比较通俗易懂的实现方案,若是想深刻了解,请了解大厂的相关产品实现方案
这两种实现方案是不同的
基于基础组件形式的拖拽:使用鼠标监听的形式
基于业务组件形式的拖拽:使用拖拽库 sortable.js便可知足需求
注:本文主要讲述基于基础组件的实现
是的,核心思路就是这么简单,
例如 基础按钮组件,也就是button的抽象数据
/** * 按钮的vuex数据映射关系 */ export function baseButton(store: any): baseNode { let dynamic = store.template.length * 10 return { activityId: guid(), editStatus: false, name: 'base-Button', text: '按钮', option: { btnType: 0, // 0 无事件 1 外部连接 2 提交表单 3 refInput: [], // 提交的input表单 inputFromUrl: '', // 数据提交的地址 urlMethod: 'get', // 提交格式 QQNum: '', // qq客服 PhoneNum: '', // 电话客福 link: '' // 按钮点击跳转地址 }, css: { top: 10 + dynamic, left: 10 + dynamic, width: 100, height: 50, zIndex: store.template.length + 1, background: 'rgba(241, 241, 241, 1)', color: 'rgba(0, 0, 0, 1)', fontSize: 18, borderColor: 'rgba(0, 0, 0, 1)', borderStyle: 'solid', borderWidth: 0, borderRadius: 0 }, animation: { animationName: '', animationDuration: 1000, // 动画时间 animationDelay: 0, // 延迟时间 animationIterationCount: 1, // 动画执行次数 animationFillMode: 'forwards' // 动画停留最后一帧 } } } 复制代码
每次,咱们点击添加组件的时候,咱们就在这个组件数据里面push一个组件抽象数据进去
主控台部分使用了vue的动态组件模块 component来渲染组件数据
核心代码
<component v-for="(item, index) in template" // vuex中的组件数据表 :key="index" :is="item.name" // 组件名 :id="item.activityId" // 组件id :css="item.css" // 组件样式 :option="item.option" // 组件行为 ></component> 复制代码
只要完成到这里,点击添加组件便可完成
鼠标拖拽是最消耗性能的地方,因此须要作好优化,去除没必要要的程序负担,因此本项目采用一个对鼠标进行进行集中化处理,减小没必要要的性能浪费
监听是否按住ctrl/command 来判断是否进行多选操做,咱们只要监听到鼠标事件,而且实时修改vuex中选中的组件的数据,便可实现拖动位置
多选状况下能够进行多选拖拽,多选删除,等等功能
// /activity_generate/src/utils/index.ts let indexCenter: any = null /** * 全局鼠标动做监听 */ export function initMouse(state) { indexCenter = document.querySelector('.index_center') // 仅监听拖拽部分鼠标事件 indexCenter.onmouseup = () => { if (state.isDown || state.roundDown) { // 通知vuex鼠标事件,具体业务请看代码 } } indexCenter.onmousemove = e => { if (state.isDown) { // 单选组件 let moveX = e.movementX let moveY = e.movementY index.dispatch('core/updatePosition', { x: moveX, y: moveY }) } if (state.roundDown) { // 多选组件 const data = { x: e.movementX, y: e.movementY } index.commit('core/updateZoom', data) } } } /** * 卸载监听 */ export function uninitMouse() { indexCenter.removeEventListener('mouseup', () => {}) indexCenter.removeEventListener('mousemove', () => {}) } 复制代码
咱们的组件数据是存储在vuex里面,组件即时数据,咱们想改变组件样式,只须要改变组件的数据便可
咱们须要获取到存储在vuex中的选中的组件的数据,经过计算属性将其读取到页面,数据使用计算属性的的get/set进行数据更新
项目里面使用的是绑定对象内部属性,改变vuex内部的值,这种作法不提倡,请使用get/set。set中提交commit修改数据
// 多是单组件 多是多组件 可能无组件 core() { let activeCore = this.$store.state.core.activeTemplate; if (activeCore.length == 1) { let form = this.$store.state.core.template.filter(e => activeCore.includes(e.activityId) )[0]; return form; } else if (activeCore.length > 1) { return this.$store.state.core.template.filter(e => activeCore.includes(e.activityId) ); } return {}; }, 复制代码
基于这种形式,咱们就能够经过修改右侧操做栏进行组件数据的改变
这个商品自己并不附带保存用户数据的接口,是面向企业/开发者的项目,全部表单数据将会提交到手动填写接口
首先给每一个input输入框进行命名,名字又啥用?后面你就知道了
接下来咱们就能够经过按钮来触发提交事件
例如: 使用post请求提交username字段到https://baidu.com
预览模式与客户端表现一致
输入框名字将会做为字段提交到设置好的后台,有了这个功能,便可完成向后台提交数据的功能,生成页面也再也不是静态页面,这更加适应营销页面的需求
对于营销页面而言,动画基本是不太须要的,不过为了拓展项目的适用性,仍是须要完成动画模块,这样在支持营销页面的状况下也能够完成推广宣传页面
动画模块依旧是依赖组件基础映射
animation: { animationName: '', animationDuration: 1000, // 动画时间 animationDelay: 0, // 延迟时间 animationIterationCount: 1, // 动画执行次数 animationFillMode: 'forwards' // 动画停留最后一帧 } 复制代码
动画系统依赖animation.css,一样适用计算属性进行组件数据的更新
这里涉及到后端,就不说太多了,简而言之,就是右击组件,保存组件到后台组件表,而后前台再用的用的时候对组件信息进行兼容性处理,这里涉及到自定义右击菜单
代码为 src/components/rightMenu/index.vue
一样设计到后端,大概思路为点击保存模板的时候,生成缩略图,并存入模板表,页面数据在存入模板数据表,而后在左侧模板内显示,点击模板的时候获取模板数据,并替换当前页面组件数据,完成模板的功能
这个功能仍是在这样相似项目中仍是很是经常使用的,例如不当心挪动了某个组件,或者不当心删除了组件,均可以进行撤销
详情实现请看文章: 基于vuex实现 撤销 与 反撤销 的plugins
此处特别鸣谢 鲁班h5 感受大佬提供试思路
移动端响应式一直是一个很大的问题,也是前期这个项目最头疼的点,目前的解决办法是统一按照375的宽度来进行使用,移动端vw设置默认计算宽度为375,这样,后台生成的px为单位的css,在前台都会按照必定比例被转成响应式的vw单位,这样便可适配移动端屏幕,通过测试,这种方案仍是表现良好的
能解决痛点,项目才有价值
目前系统还不支持多页滑动的状况,不事后期都会加的,这个系统初衷就是完成营销页面,解放部分前端开发者的工做量,后期越写越感受或许这个项目还能够有进步空间,未来能够作成易企秀这样的产品,同时支持第三方接入,更加适合企业私有化部署,以及接入
基本思路与基于基础组件的思路是同样的,可是须要在后台与客户端写两套代码,而后提取共有的部分,进行配置
思路是差很少的,例如商品组件,整体布局是固定的,因此这部分先后端写死,惟一变化的是里面的数据,那么咱们只须要配置变化部分就好,基于这样的思路,咱们只须要定义好业务组件的数据结构,那么后面就都是工做量的问题了,相对来讲基于业务的组件比基于基础组件的实现更加简单,只须要填充数据到业务组件里面去能够实现了
基于这种实现,前端开发就有了给用户调整的能力了,内边距不够?配置一下padding,你要多大本身调~~
本文就到到这里啦,如需交流请加交流群
或者添加做者微信: w2467230789
都看到这里了,Star一下吧