본문 바로가기
개발/게시판 만들기

[Vue] Vue.js 게시판 만들기 8 - 게시글 생성, 수정, 삭제

by onethejay 2022. 3. 3.
728x90

게시글 생성 (CREATE)

게시글 생성 부터 진행해보도록 하겠습니다.
BoardList.vue 에서 등록 버튼을 누르면 fnWrite 함수를 호출하도록 작업했습니다.
vue-router에서 생성 화면으로 연결하고 저장까지 진행해보겠습니다.

router/index.js에 먼저 write로 이동할 수 있게 추가합니다.

import { createRouter, createWebHistory } from 'vue-router'
import PageHome from '@/views/PageHome.vue'
import BoardList from '@/views/board/BoardList.vue'
import BoardDetail from '@/views/board/BoardDetail.vue'
import BoardWrite from '@/views/board/BoardWrite.vue'

const routes = [
  {
    path: '/',
    name: 'PageHome',
    component: PageHome
  },
  {
    path: '/about',
    name: 'PageAbout',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/PageAbout.vue')
  },
  {
    path: '/board/list',
    name: 'BoardList',
    component: BoardList
  },
  {
    path: '/board/detail',
    name: 'BoardDetail',
    component: BoardDetail
  },
  {
    path: '/board/write',
    name: 'BoardWrite',
    component: BoardWrite
  },

]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

이어서 views/board/BoardWrite.vue 파일을 생성해줍니다.
현재 화면에 접근했을때, 넘어온 idx가 있으면 서버를 조회해서 글을 수정할 수 있게(UPDATE) 하고, idx가 없으면 신규로 글을 작성할 수 있게(CREATE) fnGetView를 마운트합니다.

<template>
  <div class="board-detail">
    <div class="common-buttons">
      <button type="button" class="w3-button w3-round w3-blue-gray" v-on:click="fnSave">저장</button>&nbsp;
      <button type="button" class="w3-button w3-round w3-gray" v-on:click="fnList">목록</button>
    </div>
    <div class="board-contents">
      <input type="text" v-model="title" class="w3-input w3-border" placeholder="제목을 입력해주세요.">
      <input type="text" v-model="author" class="w3-input w3-border" placeholder="작성자를 입력해주세요." v-if="idx === undefined">
    </div>
    <div class="board-contents">
      <textarea id="" cols="30" rows="10" v-model="contents" class="w3-input w3-border" style="resize: none;">
      </textarea>
    </div>
    <div class="common-buttons">
      <button type="button" class="w3-button w3-round w3-blue-gray" v-on:click="fnSave">저장</button>&nbsp;
      <button type="button" class="w3-button w3-round w3-gray" v-on:click="fnList">목록</button>
    </div>
  </div>
</template>

<script>
export default {
  data() { //변수생성
    return {
      requestBody: this.$route.query,
      idx: this.$route.query.idx,

      title: '',
      author: '',
      contents: '',
      created_at: ''
    }
  },
  mounted() {
    this.fnGetView()
  },
  methods: {
    fnGetView() {
      if (this.idx !== undefined) {
        this.$axios.get(this.$serverUrl + '/board/' + this.idx, {
          params: this.requestBody
        }).then((res) => {
          this.title = res.data.title
          this.author = res.data.author
          this.contents = res.data.contents
          this.created_at = res.data.created_at
        }).catch((err) => {
          console.log(err)
        })
      }
    },
    fnList() {
      delete this.requestBody.idx
      this.$router.push({
        path: './list',
        query: this.requestBody
      })
    },
    fnView(idx) {
      this.requestBody.idx = idx
      this.$router.push({
        path: './detail',
        query: this.requestBody
      })
    },
    fnSave() {
      let apiUrl = this.$serverUrl + '/board'
      this.form = {
        "idx": this.idx,
        "title": this.title,
        "contents": this.contents,
        "author": this.author
      }

      if (this.idx === undefined) {
        //INSERT
        this.$axios.post(apiUrl, this.form)
        .then((res) => {
          alert('글이 저장되었습니다.')
          this.fnView(res.data.idx)
        }).catch((err) => {
          if (err.message.indexOf('Network Error') > -1) {
            alert('네트워크가 원활하지 않습니다.\n잠시 후 다시 시도해주세요.')
          }
        })
      } else {
        //UPDATE
        this.$axios.patch(apiUrl, this.form)
        .then((res) => {
          alert('글이 저장되었습니다.')
          this.fnView(res.data.idx)
        }).catch((err) => {
          if (err.message.indexOf('Network Error') > -1) {
            alert('네트워크가 원활하지 않습니다.\n잠시 후 다시 시도해주세요.')
          }
        })
      }
    }
  }
}
</script>
<style scoped>

</style>

목록에서 등록 버튼을 눌러 화면에 접근합니다. 제목과 작성자, 글 내용을 누르고 저장을 눌러봅니다.
img.png

새로 작성된 게시글을 확인할 수 있습니다.
img.png

게시글 목록에서도 확인이 가능합니다.
img.png

게시글 수정 (UPDATE)

이전 포스팅에서 게시글 상세보기 (BoardDetail.vue) 화면을 작업할 때 미리 수정과 삭제 함수를 생성해두었습니다.
수정 버튼을 클릭하면 BoardWrite.vue로 이동하며 마운트되어있는 fnGetView 함수가 호출되어 해당 글을 수정할 수 있게 변경됩니다.
img.png

아래는 제목과 내용을 변경하고 저장한 글입니다.
img.png

게시글 삭제 (DELETE)

게시글 삭제를 원한다면 삭제 버튼을 클릭합니다. 삭제할것인지 묻는 창이 나타나며 삭제를 원한다면 확인을 누릅니다.
img.png

생성한 게시글이 삭제된 것을 확인할 수 있습니다.
img.png

728x90

댓글