Vue3.0基于vue-grid-layout插件实现拖拽布局
最近遇到个需求需要对页面布局进行拖拽然后改变布局,保存布局插件 首先,我们选择的插件是vue-grid-layout
npm i vue-grid-layout --save
【Vue3.0基于vue-grid-layout插件实现拖拽布局】官网:https://jbaysolutions.github....
插曲 安装完依赖,发现项目能启动起来,按照官网demo发现页面空白,控制台提示没有找到子组件
改变思路,不使用局部引入组件,使用全局引入组件。
实现
const layout = ref([
{ 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 },
]);
{{ item.i }}
效果:
文章图片
但是!!
这里拖拽完没有判断每一行是否填充满且拖拽后有模块会被覆盖导致出现空白区域,如下:
文章图片
思考 我们需要增加校验,校验每一行是否填充满
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): 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 = https://www.it610.com/article/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 = https://www.it610.com/article/cloneDeep(layout.value);
// const flag = verifyLayout(layout.value);
// if (flag) {
//goBack()
// }
};
const goBack = () => {
console.log(historyDataList.value[historyDataList.value.length - 1]);
layout.value = https://www.it610.com/article/historyDataList.value[historyDataList.value.length - 1];
nowLayoutData.value = cloneDeep(layout.value);
historyDataList.value.pop();
}
这样的话每次我们拖拽完校验如果不合法就会回滚,就能保证每一行填充满了!!!!
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 基于爱,才会有“愿望”当“要求”。2017.8.12
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- 韵达基于云原生的业务中台建设 | 实战派
- EasyOA|EasyOA 基于SSM的实现 未完成总结与自我批判
- 基于stm32智能风扇|基于stm32智能风扇_一款基于STM32的智能灭火机器人设计
- stm32|基于STM32和freeRTOS智能门锁设计方案
- Python|Python 基于datetime库的日期时间数据处理