最近遇到个需要须要对页面布局进行拖拽而后扭转布局,保留布局

插件

首先,咱们抉择的插件是vue-grid-layout

npm i vue-grid-layout --save

官网:https://jbaysolutions.github....

插曲

装置完依赖,发现我的项目能启动起来,依照官网demo发现页面空白,控制台提醒没有找到子组件

扭转思路,不应用部分引入组件,应用全局引入组件。

实现

 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>

成果:

然而!!
这里拖拽完没有判断每一行是否填充斥且拖拽后有模块会被笼罩导致呈现空白区域,如下:

思考

咱们须要减少校验,校验每一行是否填充斥
1.校验函数

import { LayoutItem } from '../types/index';import { cloneDeep } from 'lodash'/** * 校验布局是否非法 * 1.深拷贝数组,防止净化原数组 * 2.拿到y的最大值 用于遍历 * 3.拿到每个y的分数组 依照x升序排列 * 4.如果数组长度为1判断w是否等于最大x * 5.如果数组长度不为1 遍历数组 判断每个元素的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;}

思路的话就是我在函数上的正文。
在每次拖拽实现的回调函数中进行校验

    /**     * 拖拽实现事件     * 1.将之前的数据存储到history数据中     * 2.而后再将挪动实现的数据存储到nowlayout数据中     */    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();    }

这样的话每次咱们拖拽完校验如果不非法就会回滚,就能保障每一行填充斥了!!!!