Vue.js 를 배워보자

Node.js, Nuxt.js, MySQL, 게시판 구현, CRUD, REST API, 프론트엔드, 백엔드, 데이터베이스, 프로그래밍, 웹 개발

_Blue_Sky_ 2024. 12. 8. 20:05
728x90
728x90

2024.11.24 - [Vue.js 를 배워보자] - Nuxt(Pinia) 게시판 페이징, 검색, RESTful API (Node.js, MySQL) 예제

 

Nuxt(Pinia) 게시판 페이징, 검색, RESTful API (Node.js, MySQL) 예제

1. 프로젝트 설정# Nuxt 프로젝트 생성npx create-nuxt-app my-board# Pinia 설치cd my-boardnpm install pinia 2. Pinia Store 설정 (store/board.js)import { defineStore } from 'pinia'import axios from 'axios'export const useBoardStore = defineSto

notion4570.tistory.com

 



기존의 게시판 구현에 게시글 작성(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