728x90
728x90
2024.11.24 - [Vue.js 를 배워보자] - Nuxt(Pinia) 게시판 페이징, 검색, RESTful API (Node.js, MySQL) 예제
기존의 게시판 구현에 게시글 작성(Create), 수정(Update), 삭제(Delete) 기능을 추가하는 방법을 설명합니다. 먼저, 백엔드에서 필요한 API를 추가하고, 프론트엔드에서 이를 호출하는 로직을 추가해야 합니다. 각 기능을 차례대로 구현해보겠습니다.
1. 게시글 작성 (Create)
(1) 백엔드 (Node.js)에서 게시글 작성 API 추가
POST /api/boards API를 추가하여, 클라이언트에서 보내는 게시글 데이터를 데이터베이스에 저장합니다.
// 게시글 작성 API 추가 (index.js)
app.post('/api/boards', async (req, res) => {
const { title, content } = req.body
// 제목과 내용이 없으면 에러 처리
if (!title || !content) {
return res.status(400).json({ message: '제목과 내용은 필수입니다.' })
}
const [result] = await pool.execute(
'INSERT INTO boards (title, content) VALUES (?, ?)',
[title, content]
)
res.status(201).json({ id: result.insertId, title, content })
})
(2) 프론트엔드 (Nuxt.js)에서 게시글 작성 폼 추가
게시글 작성 폼을 추가하고, 사용자 입력을 받아 서버로 전송합니다.
<!-- components/BoardCreate.vue -->
<template>
<div>
<h2>게시글 작성</h2>
<form @submit.prevent="createBoard">
<input type="text" v-model="title" placeholder="제목" required />
<textarea v-model="content" placeholder="내용" required></textarea>
<button type="submit">작성</button>
</form>
</div>
</template>
<script>
import { useBoardStore } from '@/store/board'
import axios from 'axios'
export default {
setup() {
const boardStore = useBoardStore()
const title = ref('')
const content = ref('')
const createBoard = async () => {
try {
const response = await axios.post('/api/boards', {
title: title.value,
content: content.value,
})
boardStore.boards.push(response.data) // 게시글 목록에 추가
title.value = ''
content.value = ''
alert('게시글이 작성되었습니다.')
} catch (error) {
console.error(error)
alert('게시글 작성에 실패했습니다.')
}
}
return { title, content, createBoard }
},
}
</script>
728x90
2. 게시글 수정 (Update)
(1) 백엔드 (Node.js)에서 게시글 수정 API 추가
PUT /api/boards/:id API를 추가하여, 특정 게시글을 수정할 수 있도록 합니다.
// 게시글 수정 API 추가 (index.js)
app.put('/api/boards/:id', async (req, res) => {
const { id } = req.params
const { title, content } = req.body
if (!title || !content) {
return res.status(400).json({ message: '제목과 내용은 필수입니다.' })
}
const [result] = await pool.execute(
'UPDATE boards SET title = ?, content = ? WHERE id = ?',
[title, content, id]
)
if (result.affectedRows > 0) {
res.json({ message: '게시글이 수정되었습니다.' })
} else {
res.status(404).json({ message: '게시글을 찾을 수 없습니다.' })
}
})
(2) 프론트엔드 (Nuxt.js)에서 게시글 수정 기능 추가
게시글 수정 페이지를 만들고, 수정 버튼을 클릭하면 API를 호출하여 데이터를 수정합니다.
<!-- components/BoardEdit.vue -->
<template>
<div>
<h2>게시글 수정</h2>
<form @submit.prevent="updateBoard">
<input type="text" v-model="title" placeholder="제목" required />
<textarea v-model="content" placeholder="내용" required></textarea>
<button type="submit">수정</button>
</form>
</div>
</template>
<script>
import { useBoardStore } from '@/store/board'
import { useRoute, useRouter } from 'vue-router'
import axios from 'axios'
export default {
setup() {
const boardStore = useBoardStore()
const route = useRoute()
const router = useRouter()
const title = ref('')
const content = ref('')
const boardId = route.params.id
// 게시글 데이터를 불러와서 수정폼에 채워넣기
const fetchBoard = async () => {
const response = await axios.get(`/api/boards/${boardId}`)
title.value = response.data.title
content.value = response.data.content
}
const updateBoard = async () => {
try {
await axios.put(`/api/boards/${boardId}`, {
title: title.value,
content: content.value,
})
alert('게시글이 수정되었습니다.')
router.push('/') // 수정 후 게시판 목록으로 이동
} catch (error) {
console.error(error)
alert('게시글 수정에 실패했습니다.')
}
}
// 페이지 로드 시 게시글 데이터 불러오기
fetchBoard()
return { title, content, updateBoard }
},
}
</script>
3. 게시글 삭제 (Delete)
(1) 백엔드 (Node.js)에서 게시글 삭제 API 추가
DELETE /api/boards/:id API를 추가하여, 특정 게시글을 삭제할 수 있도록 합니다.
// 게시글 삭제 API 추가 (index.js)
app.delete('/api/boards/:id', async (req, res) => {
const { id } = req.params
const [result] = await pool.execute(
'DELETE FROM boards WHERE id = ?',
[id]
)
if (result.affectedRows > 0) {
res.json({ message: '게시글이 삭제되었습니다.' })
} else {
res.status(404).json({ message: '게시글을 찾을 수 없습니다.' })
}
})
(2) 프론트엔드 (Nuxt.js)에서 게시글 삭제 기능 추가
게시글 목록에서 삭제 버튼을 클릭하면 해당 게시글을 삭제하는 기능을 추가합니다.
<!-- components/BoardList.vue (삭제 기능 추가) -->
<template>
<div>
<input type="text" v-model="searchKeyword" @input="searchBoards" />
<ul>
<li v-for="board in boards" :key="board.id">
{{ board.title }}
<button @click="deleteBoard(board.id)">삭제</button>
</li>
</ul>
<button @click="prevPage">이전</button>
<button @click="nextPage">다음</button>
</div>
</template>
<script>
import { useBoardStore } from '@/store/board'
import axios from 'axios'
export default {
setup() {
const boardStore = useBoardStore()
const searchBoards = (keyword) => {
boardStore.searchBoards(keyword)
}
const prevPage = () => {
boardStore.currentPage--
boardStore.fetchBoards()
}
const nextPage = () => {
boardStore.currentPage++
boardStore.fetchBoards()
}
const deleteBoard = async (id) => {
try {
await axios.delete(`/api/boards/${id}`)
boardStore.boards = boardStore.boards.filter(board => board.id !== id) // 목록에서 삭제된 게시글 제거
alert('게시글이 삭제되었습니다.')
} catch (error) {
console.error(error)
alert('게시글 삭제에 실패했습니다.')
}
}
return {
boards: boardStore.boards,
searchKeyword: boardStore.searchKeyword,
searchBoards,
prevPage,
nextPage,
deleteBoard,
}
},
}
</script>
728x90
4. MySQL 테이블 수정
게시글 수정, 삭제 기능을 추가하려면, 게시글을 식별할 수 있는 id가 필요하므로 기존 테이블에 id 컬럼이 이미 존재한다고 가정합니다.
테이블 생성 예시
CREATE TABLE boards (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
결론
이제 Nuxt.js와 Pinia를 사용하여 게시글 작성, 수정, 삭제 기능을 추가했습니다. 각 기능은 RESTful API를 통해 Node.js 서버와 통신하며, MySQL 데이터베이스에 반영됩니다.
728x90
728x90
'Vue.js 를 배워보자' 카테고리의 다른 글
Vue.js 애플리케이션 포트 설정: 유연하고 효율적인 개발 환경 구축 가이드 (0) | 2024.12.10 |
---|---|
npm run serve 한뒤에 정지를 하려면? (0) | 2024.12.10 |
Nuxt에서 Pinia를 활용한 페이징된 그리드 데이터 바인딩 (0) | 2024.11.30 |
Vue.js와 Vue CLI의 관계? (1) | 2024.11.30 |
import { io } from 'socket.io-client';에서 {}의 유무차이 (0) | 2024.11.25 |