(開源)從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一下吧

易動

相關文章
相關標籤/搜索