整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          如何絲滑的實現首頁看板拖拉拽功能?

          求簡介

          最近接了一個需求,需要實現不同登錄人員可以自定義首頁模塊卡片。簡單來說,就是實現首頁看板模塊的增添拖拉拽,效果如下:

          技術選型

          原生js是支持拖拉拽的,只需要將拖拽的元素的 draggable 屬性設置成 "true"即可,然后就是調用相應的函數即可。

          拖拽操作 - Web API 接口參考 | MDN

          但是,原生js功能不夠完善,使用起來需要改造的地方很多,因此,選用成熟的第三方插件比較好。

          我們的主項目采用的是vue3,,經過一系列對比,最終選擇了 vue-draggable-next這個插件。

          vue-draggable-next

          vue-draggable-next的周下載量月3萬左右,可以看出是一個比較靠譜的插件。

          它的使用方式npmj上也介紹的很詳細:

          vue-draggable-next

          如果英文的使用Api看起來比較難受,網上還有中文的使用文檔:

          vue.draggable.next 中文文檔 - itxst.com

          這個插件也有vue2版本和純js版本,其他框架也是也是可以完美使用的。

          實現思路

          需求與技術簡析

          根據我們的需求,我們應該實現的是分組拖拽,假設我們有三列,那我們要實現的就是這A、B、C三列數據相互拖拽。

          我們看看中文官網給的示例:

          vue.draggable.next group 例子

          看起來很容易,我們只需要寫多個draggable標簽,每個draggable標簽寫入相同的組名即可。

          實現方案

          框架實現

          回到代碼中,要想實現一個三列可拖拉拽的模塊列表,我們首先需要引入組件

          <script lang="ts" setup>
          import { VueDraggableNext } from 'vue-draggable-next'
          // ....
          </script>
          


          然后定義一個數組儲存數據:

          <script lang="ts" setup>
              import { VueDraggableNext } from 'vue-draggable-next'
              const moduleList = ref([
                {
                  "columnIndex": 1,
                  "moduleDetail": [
                    { "moduleCode": "deviation", "moduleName": "控制失調空間",},
                    { "moduleCode": "meeting_pending", "moduleName": "會議待辦",},
                    { "moduleCode": "abnormal_events", "moduleName": "異常事件", },
                    { "moduleCode": "audit_matters", "moduleName": "事項審批",}
                  ],
                },
                {
                  "columnIndex": 2,
                  "moduleDetail": [
                    { "moduleCode": "air_conditioning_terminal", "moduleName": "空調末端", }
                  ],
                },
                {
                  "columnIndex": 3,
                  "moduleDetail": [
                    { "moduleCode": "run_broadcast", "moduleName": "運行播報",},
                    {"moduleCode": "my_schedule", "moduleName": "我的日程", },
                    { "moduleCode": "cold_station", "moduleName": "冷站",}
                  ],
                }
              ])
          </script>
          


          最后,在代碼中我們使用v-for循環渲染即可

          <div v-for="moduleColumn in  moduleList " :key="moduleColumn.columnIndex" class="box">
            <VueDraggableNext :list="moduleColumn.moduleDetail" group="column" >
              <div v-for="(item, index) in  moduleColumn.moduleDetail " :key="item.moduleCode" class="drag-item">
                <!-- 模塊內容 -->
              </div>
            </VueDraggableNext>
          </div>
          


          注意上面的html結構,我們循環渲染了三列VueDraggableNext標簽,每個VueDraggableNext標簽內部又通過v-for="(item, index) in moduleColumn.moduleDetail渲染了這個拖拽列內部的所有模塊。我們通過group="column" 讓每個VueDraggableNext組件的組名相同,實現了三個拖拽標簽之間的模塊互相拖拉拽。

          拖拽點設置

          正常情況小,我們肯定是希望在某個組件的固定位置才能拖動組件,因此我們需要使用到拖拽組件的handle屬性。

          vue.draggable.next屬性說明:

          handle

          :handle=".mover" 只有當鼠標在class為mover類的元素上才能觸發拖到事件

          根據屬性說明,我們的代碼實現起來也非常容易了。

            <div v-for="moduleColumn in  moduleList " :key="moduleColumn.columnIndex" class="box">
                <VueDraggableNext :list="moduleColumn.moduleDetail" handle=".move" group="column">
                  <div v-for="(item, index) in  moduleColumn.moduleDetail " :key="item.moduleCode" class="drag-item">
                    <div class="move">
                      拖拽區域
                    </div>
                    <!-- 模塊內容 -->
                  </div>
                </VueDraggableNext>
            </div>
          


          數據的增刪改

          實際開發中,我么一定會根據接口或者操作動態的更改列表,代碼層也就是更改moduleList的值。非常幸運的是,如果你按照上面的方式寫代碼,當你拖拉拽完畢后,上面的moduleList值會自動更改,我們不用做任何處理!!!這么看,數據的增刪改根本不是問題。

          如何動態渲染組件

          實際開發中,我們可能會遇到一個問題,就是如何動態的去渲染組件,如果你熟悉vue,使用動態組件component就可以實現。

          首先,我們需要定義一個模塊列表

          import MeetingPending from '../components/meetingPending.vue'
          import AbnormalEvents from '../components/abnormalEvents/index.vue'
          import MySchedule from '../components/mySchedule.vue'
          import TransactionApproval from '../components/transactionApproval.vue'
          import RunningBroadcast from '../components/runningBroadcast.vue'
          import CodeSite from '../components/codeSite/index.vue'
          import MismatchSpace from '../components/mismatchSpace/index.vue'
          import AirDevice from '../components/airDevice/index.vue'
          
          // !全量模塊選擇列表
          export const allModuleList = [
            { moduleCode: 'meeting_pending', label: '會議待辦', component: MeetingPending },
            { moduleCode: 'my_schedule', label: '我的日程', component: MySchedule },
            { moduleCode: 'audit_matters', label: '事項審批', component: TransactionApproval },
            { moduleCode: 'abnormal_events', label: '異常事件', component: AbnormalEvents },
            { moduleCode: 'deviation', label: '控制失調空間', component: MismatchSpace },
            { moduleCode: 'run_broadcast', label: '運行播報', component: RunningBroadcast },
            { moduleCode: 'cold_station', label: '冷站', component: CodeSite },
            { moduleCode: 'air_conditioning_terminal', label: '空調末端', component: AirDevice }
          ]
          


          然后根據moduleCode做匹配,動態渲染即可

            <div v-for="moduleColumn in  moduleList " :key="moduleColumn.columnIndex" class="box">
                <VueDraggableNext :list="moduleColumn.moduleDetail" handle=".move" group="column">
                  <div v-for="(item, index) in  moduleColumn.moduleDetail " :key="item.moduleCode" class="drag-item">
                    <div class="move">
                      拖拽區域
                    </div>
                    <component :is="getComponentsByCode(item.moduleCode)" ></component>
                  </div>
                </VueDraggableNext>
            </div>
          


          更多定制化需求

          如果上面的功能不滿足你的需求,我們可以使用這個組件的其他屬性,完成更多意想不到的效果

          如果下面的屬性說明未能完全看明,可以看左邊的對應的菜單查看詳細說明和例子。

          屬性名稱

          說明

          group

          如果一個頁面有多個拖拽區域,通過設置group名稱可以實現多個區域之間相互拖拽 或者 { name: "...", pull: [true, false, 'clone', array , function], put: [true, false, array , function] }

          sort

          是否開啟排序,如果設置為false,它所在組無法排序

          delay

          鼠標按下多少秒之后可以拖拽元素

          touchStartThreshold

          鼠標按下移動多少px才能拖動元素

          disabled

          :disabled= "true",是否啟用拖拽組件

          animation

          拖動時的動畫效果,如設置animation=1000表示1秒過渡動畫效果

          handle

          :handle=".mover" 只有當鼠標在class為mover類的元素上才能觸發拖到事件

          filter

          :filter=".unmover" 設置了unmover樣式的元素不允許拖動

          draggable

          :draggable=".item" 樣式類為item的元素才能被拖動

          ghost-class

          :ghost-class="ghostClass" 設置拖動元素的占位符類名,你的自定義樣式可能需要加!important才能生效,并把forceFallback屬性設置成true

          chosen-class

          :ghost-class="hostClass" 被選中目標的樣式,你的自定義樣式可能需要加!important才能生效,并把forceFallback屬性設置成true

          drag-class

          :drag-class="dragClass"拖動元素的樣式,你的自定義樣式可能需要加!important才能生效,并把forceFallback屬性設置成true

          force-fallback

          默認false,忽略HTML5的拖拽行為,因為h5里有個屬性也是可以拖動,你要自定義ghostClass chosenClass dragClass樣式時,建議forceFallback設置為true

          fallback-class

          默認false,克隆選中元素的樣式到跟隨鼠標的樣式

          fallback-on-body

          默認false,克隆的元素添加到文檔的body中

          fallback-tolerance

          按下鼠標移動多少個像素才能拖動元素,:fallback-tolerance="8"

          scroll

          默認true,有滾動區域是否允許拖拽

          scroll-fn

          滾動回調函數

          scroll-fensitivity

          距離滾動區域多遠時,滾動滾動條

          scroll-speed

          滾動速度

          傳送門:vue.draggable.next 中文文檔 - itxst.com

          寫在最后

          關聯文章:如何實現模塊的錨點定位及閃爍提示:juejin.cn/post/734622…


          作者:石小石Orz
          鏈接:https://juejin.cn/post/7346121373112811583

          段時間使用了一下ActionTab感覺這個產品,小編也想向這個產品學習學習,自己開發一個工具箱。就當是學習總結之用了,有興趣的小伙伴可以私信小編獲取代碼,后續等功能界面稍微成型了再放到github上開源(現在有些拿不出手)~~~

          今天想實現的樣子

          我感覺便利貼應該算是ActionTab上比較方便的功能,因此我們也從便利貼功能組件開始。

          便利貼功能需要做到兩點:可拖拉拽;可縮放;用戶可輸入。效果如下:

          拖拉拽效果

          拖拉拽組件

          • 拖拉拽組件很早之前也看過一些實現方法,HTML元素本身就是有個draggable的屬性的,不過實現起來都比較麻煩,為什么不站在巨人的肩膀上呢?行吧,那就站在巨人的肩膀上吧。。。
          • 我們選擇的可拖拉拽的組件叫:vue3-draggable-resizable,安裝命令如下:
          npm i vue3-draggable-resizable
          • 這個組件的使用也非常簡單,以下是這個組件的大致用法。
          // JS代碼
          import "vue3-draggable-resizable/dist/Vue3DraggableResizable.css";
          import Vue3DraggableResizable from "vue3-draggable-resizable";
          
          // 模板代碼
          <Vue3DraggableResizable
              :initW="props.config.w"
              :initH="props.config.h"
              v-model:x="props.config.x"
              v-model:y="props.config.y"
              v-model:w="props.config.w"
              v-model:h="props.config.h"
              :draggable="true"
              :resizable="true"
              @activated="print('activated')"
              @deactivated="print('deactivated')"
              @drag-start="print('drag-start')"
              @drag-end="console.log"
              @resize-start="(e) => emits('resizeStart', e)"
              @resizing="(e) => emits('resizing', e)"
              @resize-end="(e) => emits('resizeEnd', e)"
              class="drag-item">
              // 內容區
            </Vue3DraggableResizable>

          實現原理

          • 通過上面的Vue3DraggableResizable+textarea實現便利貼可拖拽、可縮放功能。
          • textarea元素無法實現根據Vue3DraggableResizable的縮放自動調整寬度和高度,因此需要需要監聽Vue3DraggableResizable的縮放事件從而計算出textarea的高度(寬度固定)。
          const resizeTextArea = () => {
            const targetParent = textareaRef.value?.closest(".drag-item");
            if (targetParent == null) {
              return;
            }
          
            const parentHeight = targetParent?.clientHeight;
            if (!parentHeight) {
              return;
            }
            const textareaHeight = parentHeight - props.config.headerHeight - 10 - 5;
            textareaRef.value!.style.height = `${textareaHeight}px`;
          };
          // 稍微增加個防抖功能,降低調用次數
          const debouncedResizeTextArea = _.debounce(resizeTextArea, 10);
          
          // 事件監聽
          @resize-start="debouncedResizeTextArea"
          @resizing="debouncedResizeTextArea"
          @resize-end="debouncedResizeTextArea"
          • 其中的props.config.headerHeight - 10 - 5;當前可拖拽組件的頭高度以及textarea自己的margin和padding。

          其他

          • 這塊功能簡單,最大的成本反而是在調樣式上。
          • 下一步小編將會把用戶的便利簽數據存儲到瀏覽器的indexDB上(小編會選擇用pinia獲得響應式能力,同時借助小編之前的一篇pinia持久化的文章將數據持久化到indexdb中),再往后我們可以將便簽數據存儲到后端(需要借助服務端的代碼).
          • 測試地址,有啥建議也一定請給小編留言:
          http://yaat.junxian.me/index.html#/

          數字化轉型的浪潮下,MISBoot低代碼開發平臺正成為越來越多企業的首選,其拖拉拽自定義表單功能更是成為業務人員的利器,實現了零代碼開發的理想。這項革新技術不僅讓業務人員輕松上手,還能直接掛載菜單應用,結合流程引擎、數據報表、電子簽章等功能,適配移動端,擁有40種組件并可自行擴展,每個組件都有獨立屬性設置,列表字段、查詢字段、列表配置都可以獨立配置,同時還具備添加顯隱規則、加載表單時觸發、提交表單前觸發、提交表單后觸發等js、css代碼的功能。這篇文章將深入探討低代碼開發平臺拖拉拽自定義表單功能的強大之處,以及它對企業數字化轉型的重要意義。

          低代碼開發平臺的崛起

          隨著數字化轉型的推進,企業對快速、靈活地開發應用程序和解決方案的需求日益增長。傳統的軟件開發過程往往耗時費力,需要專業的編程技能和繁瑣的代碼編寫,這給業務人員帶來了很大的挑戰。然而,低代碼開發平臺的崛起改變了這一局面。低代碼開發平臺為業務人員提供了一種全新的開發范式,使他們可以通過直觀的圖形界面和拖拉拽操作就能創建應用程序,無需編寫一行代碼。其中的拖拉拽自定義表單功能更是低代碼開發平臺的一大特色,讓業務人員可以輕松定制和調整表單布局,設定字段的驗證規則,配置列表顯示和查詢條件,實現了真正意義上的零代碼開發。

          拖拉拽自定義表單的魅力

          基于MISBoot低代碼開發平臺的拖拉拽自定義表單功能簡直是讓業務人員擁有了無限的可能性。這項功能使得業務人員能夠根據實際需求,輕松創建符合自身業務流程的數據輸入界面,無需編寫一行代碼。通過簡單的拖拉拽和配置,就能完成一個完整的數據輸入表單,包括40種組件可供選擇,并且每個組件都有獨立的屬性設置,滿足了各種不同的業務需求。同時,拖拉拽自定義表單功能適配移動端,使得用戶可以在手機端便捷地進行表單操作,大大提升了工作效率和靈活性。

          靈活性與擴展性的兼顧

          拖拉拽自定義表單的靈活性和擴展性也是其獨特之處。每個組件都可以執行擴展,使得平臺可以適應各種復雜的業務場景。同時,列表字段、查詢字段、列表配置都可以獨立配置,為用戶提供了更多的個性化選擇,滿足了不同用戶的特定需求。此外,拖拉拽自定義表單還具備添加顯隱規則、表單時觸發、提交表單前觸發、提交表單后觸發等js、css代碼的功能,讓用戶可以根據實際需求進行更加靈活的定制和擴展,實現更多樣化的業務邏輯。

          未來展望

          MISBoot低代碼開發平臺 - 基于Spring Cloud微服務架構的拖拉拽自定義表單功能正在成為企業數字化轉型的利器,它將業務人員從繁瑣的編程工作中解放出來,使他們能夠更專注于業務需求的實現和創新。隨著技術的不斷演進和平臺功能的不斷完善,相信拖拉拽自定義表單將在未來發揮越來越重要的作用,成為企業應用開發的標配工具之一。

          結語

          MISBoot低代碼開發平臺 - 基于Spring Cloud微服務架構的拖拉拽自定義表單功能不僅實現了零代碼開發的夢想,更讓業務人員輕松上手,為企業數字化轉型注入了強大的活力和創造力。其靈活性、擴展性以及適配移動端的特點,將為企業帶來更高效的業務流程和更好的用戶體驗,助力企業持續創新與發展。隨著其不斷的演進和普及,必將成為企業信息化建設的重要推動力量,為企業贏得更多商業機會和競爭優勢。

          圖片展示

          表單分類使業務更清晰

          在線設計管理

          表單在線系統配置界面

          表單數據配置界面

          桌面端表單設計區,豐富的組件及屬性配置

          移動端表單設計區,豐富的組件及屬性配置

          豐富的桌面端、移動端列表字段、查詢字段、列表配置

          多種表單預覽方式

          直接掛載菜單,掛載直接使用

          直接綁定數據報表功能

          直接綁定數據報表功能在線打印等

          表單預覽功能


          主站蜘蛛池模板: 国产综合视频在线观看一区| 欧洲无码一区二区三区在线观看| 亚洲国产一区二区a毛片| 国产精品无码一区二区三级| 成人精品视频一区二区| 福利视频一区二区牛牛| 亚洲视频一区网站| 激情内射日本一区二区三区| 中日韩精品无码一区二区三区| 插我一区二区在线观看| 丰满岳妇乱一区二区三区| 色窝窝无码一区二区三区色欲| 亚洲一区免费视频| 能在线观看的一区二区三区| 色偷偷久久一区二区三区| 国产AV午夜精品一区二区三| 国产精品免费一区二区三区| 日本精品一区二区三区四区| 免费高清在线影片一区| 欧美日韩综合一区二区三区| 国产美女一区二区三区| 亚洲高清一区二区三区电影| 国模私拍福利一区二区| 五十路熟女人妻一区二区| 亚洲丰满熟女一区二区哦| 日韩AV片无码一区二区不卡| 国产精品无码一区二区三区在| 最新中文字幕一区| 精品一区二区三区在线观看l| 精品国产一区二区三区香蕉| 伊人久久精品无码麻豆一区| 亚洲日韩一区二区一无码| 国产精品久久久久一区二区| 大屁股熟女一区二区三区| 久久人做人爽一区二区三区| 色噜噜狠狠一区二区三区果冻| 精品无码日韩一区二区三区不卡 | 国产精品一区在线观看你懂的| 亚洲AV无码一区二三区| 久久一区二区三区99| 亚洲av无码一区二区三区观看|