Vue3.0利用vue-grid-layout插件實(shí)現(xiàn)拖拽布局
1、插件
首先,我們選擇的插件是vue-grid-layout
npm i vue-grid-layout --save
官網(wǎng):https://jbaysolutions.github....
2、插曲
安裝完依賴,發(fā)現(xiàn)項(xiàng)目能啟動(dòng)起來(lái),按照官網(wǎng)demo發(fā)現(xiàn)頁(yè)面空白,控制臺(tái)提示沒有找到子組件
改變思路,不使用局部引入組件,使用全局引入組件。
3、實(shí)現(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>
效果:

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

思考:
我們需要增加校驗(yàn),校驗(yàn)每一行是否填充滿
4、校驗(yàn)函數(shù)
import { LayoutItem } from '../types/index';
import { cloneDeep } from 'lodash'
/**
* 校驗(yàn)布局是否合法
* 1.深拷貝數(shù)組,避免污染原數(shù)組
* 2.拿到y(tǒng)的最大值 用于遍歷
* 3.拿到每個(gè)y的分?jǐn)?shù)組 按照x升序排列
* 4.如果數(shù)組長(zhǎng)度為1判斷w是否等于最大x
* 5.如果數(shù)組長(zhǎng)度不為1 遍歷數(shù)組 判斷每個(gè)元素的w是否等于下一個(gè)元素的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('多個(gè)個(gè)-------------------', 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('只有一個(gè)-------------------', i);
if (arr[0].w !== maxX) {
flag = true
}
}
}
console.log(flag);
return flag;
}
思路的話就是我在函數(shù)上的注釋。
在每次拖拽完成的回調(diào)函數(shù)中進(jìn)行校驗(yàn)
/**
* 拖拽完成事件
* 1.將之前的數(shù)據(jù)存儲(chǔ)到history數(shù)據(jù)中
* 2.然后再將移動(dòng)完成的數(shù)據(jù)存儲(chǔ)到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();
}
這樣的話每次我們拖拽完校驗(yàn)如果不合法就會(huì)回滾,就能保證每一行填充滿了?。。?!
到此這篇關(guān)于Vue3.0利用vue-grid-layout插件實(shí)現(xiàn)拖拽布局的文章就介紹到這了,更多相關(guān)Vue3 利用vue-grid-layout插件實(shí)現(xiàn)拖拽布局內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項(xiàng)目中圖片懶加載時(shí)出現(xiàn)的問(wèn)題及解決
這篇文章主要介紹了vue項(xiàng)目中圖片懶加載時(shí)出現(xiàn)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
詳解Vue ElementUI手動(dòng)上傳excel文件到服務(wù)器
這篇文章主要介紹了詳解Vue ElementUI手動(dòng)上傳excel文件到服務(wù)器,對(duì)ElementUI感興趣的同學(xué),可以參考下2021-05-05
vue props傳值失敗 輸出undefined的解決方法
今天小編就為大家分享一篇vue props傳值失敗 輸出undefined的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue.js異步上傳文件前后端實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了vue.js異步上傳文件前后端的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08

