2021.04.08
😊 2021.04.08
1. Vue slot을 활용한 컴포넌트 재활용
2. 뷰 컴포넌트 props 타입이 배열이나 객체인 경우
팩토리 패턴으로 작성해야함.
3. 슬롯에 데이터바인딩
: https://beomy.tistory.com/58
4. hsla?
border-color: hsla(0, 0%, 100%, 0.5);
5. bin-packing algorithm 알고리즘
6. javascript json 파싱 에러 처리
if (typeof positions == "string") {
try {
// 성공
positions = JSON.parse(positions);
onSuccess(positions);
} catch (error) {
// 실패
console.error("JSON parse error: " + error);
onError();
return;
}
}
7. Packery 라이브러리 자동 빈 공간 채우기 방지
- 참고
- https://github.com/metafizzy/packery/issues/337
- https://packery.metafizzy.co/#initialize-with-vanilla-javascript
- https://jeonghwan-kim.github.io/2018/05/12/extended-component.html
- HTML
// html
<div class="grid" id="grid">insert html</div>
- CSS
/*css*/
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- grid ---- */
.grid {
background: #ddd;
width: 100%;
max-width: 800px;
min-width: 400px;
min-height: 400px;
}
/* clear fix */
.grid:after {
content: "";
display: block;
clear: both;
}
/* ---- .grid-item ---- */
.grid-item {
float: left;
width: 25%;
height: 100px;
background: #c09;
border: 2px solid hsla(0, 0%, 0%, 0.5);
}
.grid-item.col-1 {
width: 100%;
}
.grid-item.col-2 {
width: 50%;
}
.grid-item.col-3 {
width: 25%;
}
.grid-item:hover {
border-color: hsla(0, 0%, 100%, 0.5);
cursor: move;
}
.grid-item.is-dragging,
.grid-item.is-positioning-post-drag {
background: #c90;
z-index: 2;
}
.packery-drop-placeholder {
outline: 3px dashed hsla(0, 0%, 0%, 0.5);
outline-offset: -6px;
-webkit-transition: -webkit-transform 0.2s;
transition: transform 0.2s;
}
- Javascript
// javascript
const $ = (selector) => document.querySelector(selector);
const gridView = {
init(el) {
console.log("[gridView init]");
const self = this;
this.el = el;
this.data = [];
// 패커리 실행
this.packery = initPackery(this.el);
// 이벤트 설정
this.packery.on("dragItemPositioned", function (draggedItem) {
self.onDragEnd(draggedItem);
});
window.packery = this.packery;
return this;
},
setData(data) {
console.log("[gridView setData]");
this.data = data;
return this;
},
render() {
console.log("[gridView render]");
this.el.innerHTML = "";
this.data.forEach((item) => {
const div = document.createElement("div");
div.setAttribute("data-id", item.id);
div.setAttribute("data-sort", item.sort);
div.className = item.className;
div.setAttribute("data-top", item.top);
div.setAttribute("data-left", item.left);
div.innerText = item.title;
this.el.appendChild(div);
});
this.initLayout();
return this;
},
// 레이아웃 그리기
initLayout() {
const self = this;
// 렌더링 후 다시 패커리 세팅
this.packery.reloadItems();
this.setItemDraggable();
this.packery._resetLayout();
const elements = this.packery.getItemElements();
try {
elements.forEach(function (element) {
const packeryItem = self.packery.getItem(element);
console.log(packeryItem);
try {
const left = element.getAttribute("data-left");
const top = element.getAttribute("data-top");
if (isNaN(left) || isNaN(top)) {
throw new Error("position error");
}
packeryItem.rect.x = +left * self.packery.packer.width;
// packeryItem.rect.y = +top * self.packery.packer.width;
packeryItem.rect.y = +top;
packeryItem.element.style.top = packeryItem.rect.y + "px";
packeryItem.element.style.left = packeryItem.rect.x + "px";
} catch (error) {
throw error;
}
});
// self.packery.shiftLayout();
} catch (error) {
console.log(error.message);
self.packery.layout();
}
},
// 드래그 앤 드롭 설정
setItemDraggable() {
this.packery.getItemElements().forEach(function (itemElem) {
var draggie = new Draggabilly(itemElem);
this.packery.bindDraggabillyEvents(draggie);
});
},
onDragEnd(draggedItem) {
const self = this;
const items = draggedItem.layout.items;
const gridWidth = self.packery.packer.width;
const newData = items.map(function (item) {
const rect = item.rect;
const element = item.element;
return {
left: rect.x / gridWidth,
// top: rect.y / gridWidth,
top: rect.y,
className: element.className,
sort: element.getAttribute("data-sort"),
id: element.getAttribute("data-id"),
title: element.innerText,
};
});
console.log(newData);
localStorage.setItem("initData", JSON.stringify(newData));
// 서버에 데이터 전송
// this.data = newData;
},
};
document.addEventListener("DOMContentLoaded", function (e) {
init();
});
function init() {
console.log("[init]");
gridView.init($("#grid"));
window.gridView = gridView;
list().then((data) => {
gridView.setData(data).render();
});
}
function list() {
console.log("[list]");
const data = [
{
id: "card-2",
title: "카드2",
className: "grid-item col-2",
sort: 2,
position: {},
},
{
id: "card-1",
title: "카드1",
className: "grid-item col-1",
sort: 1,
position: {},
},
{
id: "card-3",
title: "카드3",
className: "grid-item col-3",
sort: 3,
position: {},
},
{
id: "card-4",
title: "카드4",
className: "grid-item col-3",
sort: 3,
position: {},
},
];
const initData = localStorage.getItem("initData");
if (typeof initData === "string") {
try {
console.log(initData);
return Promise.resolve(JSON.parse(initData));
} catch (error) {
return Promise.resolve(data);
}
} else {
return Promise.resolve(data);
}
}
// 패커리 실행
function initPackery(el) {
console.log("[initPackery]");
const pckry = new Packery(el, {
itemSelector: ".grid-item",
columnWidth: 100,
initLayout: false,
});
return pckry;
}
Author And Source
이 문제에 관하여(2021.04.08), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kyh196201/2021.04.08저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)