(开源)从0打造H5可视化搭建系统 - 易动(vue+ts+egg)

前端工程师是有极限的javascript

我从短暂的工做当中学到一件事......css

越是熬夜加班,就越会发现人类的能力是有极限的......前端

除非超越产品vue

我不加班了!!BOSSjava

拖拽生成h5页面,支持动画,模板,保存组件,第三方后台接入提交数据,欢迎体验git

基于vue搭建营销h5页面 易动 已上线,欢迎体验~~github

开源不易,给个Star吧~vuex

前言

面对频繁变动的页面需求,面对客户像爱情同样的的需求(文字小一点,边距小一点),你是否是也曾经抓狂过,是否是也想说出内心的声音,我不想加班后端

img

因此对于特定的业务场景,例如活动页面,以及首页,这种常常须要修改的页面,彻底能够经过搭建进行完成,目前市场上搭建前端页面能够分为两类微信

  1. 易企秀 此类交互偏弱,可是组件是基于基础组件的,而且调整更加灵活,可上下左右拖拽,例如按钮,图片
  2. 有赞、酷客多 基于业务组件进行搭建,此类偏固定,组件以行为单位,只可调整上下,例如搜索组件、活动组件,图片组组件

img

实现方式是不少种的,本文提出的是一种比较通俗易懂的实现方案,若是想深刻了解,请了解大厂的相关产品实现方案

这两种实现方案是不同的

基于基础组件形式的拖拽:使用鼠标监听的形式

基于业务组件形式的拖拽:使用拖拽库 sortable.js便可知足需求

注:本文主要讲述基于基础组件的实现

业务实现

核心实现思路

img

是的,核心思路就是这么简单,

定制组件数据结构

例如 基础按钮组件,也就是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' // 动画停留最后一帧
    }
  }
}
复制代码

在vuex中维护一个页面数据对象

每次,咱们点击添加组件的时候,咱们就在这个组件数据里面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输入框进行命名,名字又啥用?后面你就知道了

img

接下来咱们就能够经过按钮来触发提交事件

例如: 使用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一下吧

易动

相关文章
相关标签/搜索