ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ Webpack๊ณผ TypeScript๋ก ๋ง๋๋ ์น์ฑ ์บ๋ฆฐ๋ ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ ์๋ฆฌ์ฆ - ์ผ์ ์ญ์ ๋ฐ ์์ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ – ์ธํฐ๋์ ๊ฐํ
octo54 2025. 3. 27. 10:51๐ Webpack๊ณผ TypeScript๋ก ๋ง๋๋ ์น์ฑ ์บ๋ฆฐ๋ ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ ์๋ฆฌ์ฆ
โ 8ํธ: ์ผ์ ์ญ์ ๋ฐ ์์ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ – ์ธํฐ๋์ ๊ฐํ
์ง๋ ๊ธ์์๋ LocalStorage ์ฐ๋์ ํตํด ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์ ์งํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ์ผ์ ์ ์์ ํ๊ฑฐ๋ ์ญ์ ํ ์ ์๋ ๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค.
์ง๊ธ๊น์ง ์ผ์ ์ ์ถ๊ฐ๋ง ๊ฐ๋ฅํ์ง๋ง,
์ค์ ์ฌ์ฉ ๊ฐ๋ฅํ ์บ๋ฆฐ๋๊ฐ ๋๋ ค๋ฉด ์ญ์ ๋ฐ ์์ ๊ธฐ๋ฅ๋ ํ์์ ์ผ๋ก ํ์ํฉ๋๋ค.
๐ฏ ๋ชฉํ
- ์ผ์ ๋ชฉ๋ก์์ ํน์ ์ผ์ ์ ์ญ์
- ์ผ์ ํด๋ฆญ ์ ์์ ๊ฐ๋ฅ
- LocalStorage ์ ๋ฐ์ดํธ๋ก ์๋ก๊ณ ์นจ ํ์๋ ๋ฐ์
๐ฆ 1. ์ผ์ ์์ ๋ฐ ์ญ์ ๋ก์ง ๋ง๋ค๊ธฐ
โ handleEditEvent() ํจ์ ์ถ๊ฐ
// src/components/EventUtils.ts
import { CalendarEvent, CalendarState } from "../types";
import { saveEvents } from "../utils/EventStorage";
export function handleEditEvent(eventId: string, state: CalendarState): void {
const event = state.events.find((e) => e.id === eventId);
if (!event) return;
const newTitle = prompt("์ ์ผ์ ์ ๋ชฉ์ ์
๋ ฅํ์ธ์:", event.title);
if (!newTitle) return;
event.title = newTitle;
saveEvents(state.events); // ๐ง ์์ ๋ ๋ฐ์ดํฐ ์ ์ฅ
}
โ handleDeleteEvent() ํจ์ ์ถ๊ฐ
export function handleDeleteEvent(eventId: string, state: CalendarState): void {
const confirmed = confirm("์ด ์ผ์ ์ ์ญ์ ํ์๊ฒ ์ต๋๊น?");
if (!confirmed) return;
state.events = state.events.filter((e) => e.id !== eventId);
saveEvents(state.events); // ๐ง ์ญ์ ํ ์ ์ฅ
}
๐ผ๏ธ 2. ์ผ์ UI์ ์์ /์ญ์ ๊ธฐ๋ฅ ์ถ๊ฐ
โ ์บ๋ฆฐ๋ ์ ์์ ์์ ๋ฐ ์ญ์ ์ด๋ฒคํธ ์ถ๊ฐ
// src/components/Calendar.ts
import { handleEditEvent, handleDeleteEvent } from "./EventUtils";
const eventHTML = eventsForDate
.map(
(e) => `
<div class="event" data-id="${e.id}">
${e.title}
<button class="edit-btn" data-id="${e.id}">โ๏ธ</button>
<button class="delete-btn" data-id="${e.id}">๐๏ธ</button>
</div>
`
)
.join("");
โ 3. ์์ ๋ฐ ์ญ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ ์ฐ๊ฒฐ
// src/components/Calendar.ts
export function attachCalendarEvents(
target: HTMLElement,
state: CalendarState,
rerender: () => void
) {
// ๊ธฐ์กด ๋ ์ง ํด๋ฆญ ํธ๋ค๋ฌ ์ ์ง
const cells = target.querySelectorAll(".calendar-cell:not(.header)");
cells.forEach((cell) => {
cell.addEventListener("click", () => {
const dateStr = cell.getAttribute("data-date");
if (dateStr) {
const date = new Date(dateStr);
state.selectedDate = date;
rerender();
}
});
});
// ์์ ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ
target.querySelectorAll(".edit-btn").forEach((btn) => {
btn.addEventListener("click", (e) => {
const eventId = (e.target as HTMLElement).getAttribute("data-id");
if (eventId) {
handleEditEvent(eventId, state);
rerender();
}
});
});
// ์ญ์ ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ
target.querySelectorAll(".delete-btn").forEach((btn) => {
btn.addEventListener("click", (e) => {
const eventId = (e.target as HTMLElement).getAttribute("data-id");
if (eventId) {
handleDeleteEvent(eventId, state);
rerender();
}
});
});
}
๐จ 4. ์คํ์ผ ์ ๋ฐ์ดํธ (์ ํ ์ฌํญ)
.event {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px 8px;
background: #f8f8f8;
margin-top: 4px;
border-radius: 4px;
}
.edit-btn,
.delete-btn {
background: none;
border: none;
cursor: pointer;
font-size: 0.8rem;
margin-left: 6px;
}
๐ 5. ํ ์คํธ
npm run dev
๐ ๏ธ ํ ์คํธ ์๋๋ฆฌ์ค
โ ์ผ์ ํด๋ฆญ ํ ์์ ๊ฐ๋ฅ:
- ์ผ์ ์ ๋ ฅ ํ, โ๏ธ ๋ฒํผ์ ํด๋ฆญ
- ์๋ก์ด ์ ๋ชฉ์ ์ ๋ ฅ
- ์ผ์ ์ด ์ ๋ฐ์ดํธ๋จ
โ ์ผ์ ์ญ์ ๊ฐ๋ฅ:
- ์ผ์ ์ ๋ ฅ ํ, ๐๏ธ ๋ฒํผ์ ํด๋ฆญ
- ํ์ธ ์ฐฝ์์ "ํ์ธ" ์ ํ
- ์ผ์ ์ด ์ญ์ ๋จ
โ ์๋ก๊ณ ์นจ ํ ๋ฐ์ดํฐ ์ ์ง:
- ์์ ๋ฐ ์ญ์ ํ์๋ LocalStorage์ ๋ฐ์๋จ์ ํ์ธ
๐ ์ฐธ๊ณ ์๋ฃ
๋ค์ ํธ ์๊ณ :
๐ 9ํธ – ์ฝ๋ ๋ฆฌํฉํ ๋ง: ํ๋ฌ๊ทธ์ธ ๊ตฌ์กฐํ ๋ฐ ์ ์ง๋ณด์ ์ต์ ํ
์ง๊ธ๊น์ง ๋ง๋ ๊ธฐ๋ฅ๋ค์ ๋ ๊น๋ํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์ฝ๋ ๊ตฌ์กฐ๋ก ๊ฐ์ ํด๋ด
๋๋ค! ๐
๋ ์ข์ ์บ๋ฆฐ๋ ํ๋ฌ๊ทธ์ธ์ ๋ง๋ค๊ธฐ ์ํด ํ ๋จ๊ณ ์
๊ทธ๋ ์ด๋! ๐ฏ
'study > ts' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- nodejs
- Docker
- Webpack
- kotlin
- REACT
- llm
- rag
- ํ๋ก ํธ์๋
- AI ์๋ํ
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- ๊ด๋ฆฌ์
- ์น๊ฐ๋ฐ
- ์ค๋งํธ ์ปจํธ๋ํธ
- seo ์ต์ ํ 10๊ฐ
- Prisma
- github
- nextJS
- App Router
- fastapi
- Ktor
- gatsbyjs
- PostgreSQL
- SEO ์ต์ ํ
- CI/CD
- LangChain
- ๋ฐฑ์๋๊ฐ๋ฐ
- NestJS
- AI์ฑ๋ด
- SEO์ต์ ํ
- Next.js
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |