Vue3.0實現(xiàn)拖拽布局

最近遇到個需求需要對頁面布局進行拖拽然后改變布局,保存布局

插件

首先,我們選擇的插件是vue-grid-layout

npm i vue-grid-layout --save

官網(wǎng):https://jbaysolutions.github.io/vue-grid-layout/zh/guide/properties.html#gridlayout

插曲

安裝完依賴,發(fā)現(xiàn)項目能啟動起來,按照官網(wǎng)demo發(fā)現(xiàn)頁面空白,控制臺提示沒有找到子組件

改變思路,不使用局部引入組件,使用全局引入組件。

實現(xiàn)

 const layout = ref<LayoutItem[]>([
      { x: 0, y: 0, w: 1, h: 1, i: 0 },
      { x: 1, y: 0, w: 2, h: 1, i: 1 },
      { x: 0, y: 1, w: 2, h: 1, i: 2 },
      { x: 0, y: 2, w: 3, h: 1, i: 3 },
      { x: 2, y: 1, w: 1, h: 1, i: 4 },
    ]);

    <grid-layout
      :layout="layout"
      :col-num="3"
      :row-height="240"
      :is-draggable="true"
      :is-resizable="true"
      :is-mirrored="false"
      :maxRows="3"
      :vertical-compact="true"
      :margin="[10, 10]"
      :use-css-transforms="true"
    >
      <grid-item
        v-for="item in layout"
        :x="item.x"
        :y="item.y"
        :w="item.w"
        :h="item.h"
        :i="item.i"
        :key="item.i"
        @moved="onItemMoved"
      >{{ item.i }}</grid-item>
    </grid-layout>

效果:


image.png

但是??!
這里拖拽完沒有判斷每一行是否填充滿且拖拽后有模塊會被覆蓋導致出現(xiàn)空白區(qū)域,如下:


image.png

思考

我們需要增加校驗,校驗每一行是否填充滿
1.校驗函數(shù)

import { LayoutItem } from '../types/index';
import { cloneDeep } from 'lodash'
/**
 * 校驗布局是否合法
 * 1.深拷貝數(shù)組,避免污染原數(shù)組
 * 2.拿到y(tǒng)的最大值 用于遍歷
 * 3.拿到每個y的分數(shù)組 按照x升序排列
 * 4.如果數(shù)組長度為1判斷w是否等于最大x
 * 5.如果數(shù)組長度不為1 遍歷數(shù)組 判斷每個元素的w是否等于下一個元素的x 累加w判斷總和是否等于最大x
 * 6.如果合法則返回false
 * @param list 
 * @returns 
 */
export const verifyLayout = (list: Array<LayoutItem>): boolean => {
    let yList = list.map(item => { return item.y });
    yList = yList.sort((a, b) => { return a - b });
    console.log(list);
    const newArr = cloneDeep(list);
    let flag = false;
    const maxY = yList[yList.length - 1];
    const maxX = 3;
    console.log(maxY);
    for (let i = 0; i <= maxY; i++) {
        let arr = newArr.filter((item: LayoutItem) => {
            return item.y === i;
        });
        console.log(arr, arr.length);
        if (arr && arr.length > 1) {
            console.log('多個個-------------------', i);
            let calValue = 0;
            arr = arr.sort((a: LayoutItem, b: LayoutItem) => { return a.x - b.x })
            arr.forEach((childItem: LayoutItem, index: number) => {
                calValue += childItem.w;
                console.log('calValue--------------', calValue, index);
                if (index !== arr.length - 1 && calValue !== arr[index + 1].x) {
                    flag = true;
                }
                if (index === arr.length - 1 && calValue !== maxX) {
                    flag = true;
                }
            })
        } else {
            console.log('只有一個-------------------', i);
            if (arr[0].w !== maxX) {
                flag = true
            }
        }
    }
    console.log(flag);
    return flag;
}

思路的話就是我在函數(shù)上的注釋。
在每次拖拽完成的回調(diào)函數(shù)中進行校驗

    /**
     * 拖拽完成事件
     * 1.將之前的數(shù)據(jù)存儲到history數(shù)據(jù)中
     * 2.然后再將移動完成的數(shù)據(jù)存儲到nowlayout數(shù)據(jù)中
     */
    const onItemMoved = () => {
      console.log('moved--------------------')
      historyDataList.value.push(cloneDeep(nowLayoutData.value));
      nowLayoutData.value = cloneDeep(layout.value);
      // const flag = verifyLayout(layout.value);
      // if (flag) {
      //   goBack()
      // }
    };
    const goBack = () => {
      console.log(historyDataList.value[historyDataList.value.length - 1]);
      layout.value = historyDataList.value[historyDataList.value.length - 1];
      nowLayoutData.value = cloneDeep(layout.value);
      historyDataList.value.pop();
    }

這樣的話每次我們拖拽完校驗如果不合法就會回滾,就能保證每一行填充滿了?。。?!

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 16宿命:用概率思維提高你的勝算 以前的我是風險厭惡者,不喜歡去冒險,但是人生放棄了冒險,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 7,594評論 0 4
  • 公元:2019年11月28日19時42分農(nóng)歷:二零一九年 十一月 初三日 戌時干支:己亥乙亥己巳甲戌當月節(jié)氣:立冬...
    石放閱讀 7,389評論 0 2
  • 今天上午陪老媽看病,下午健身房跑步,晚上想想今天還沒有斷舍離,馬上做,衣架和旁邊的的布衣架,一看亂亂,又想想自己是...
    影子3623253閱讀 3,056評論 3 8

友情鏈接更多精彩內(nèi)容