vue + jpa project (12) - 게시판 등록, 상세, 수정, 삭제 본문

프로그램/Vue.js

vue + jpa project (12) - 게시판 등록, 상세, 수정, 삭제

반응형

게시판 리스트 처리가 마무리되어서 등록, 상세, 수정, 삭제를 진행해본다.

 

우선 신규등록과 상세보기 기능에 맞는 vue파일을 먼저 (views/board/ 아래)생성하고 board 라우터에 모두 등록한다.

// board.js
import BoardList from '@/views/board/BoardList.vue'
import BoardDetail from '@/views/board/BoardDetail.vue'
import BoardWrite  from '@/views/board/BoardWrite.vue'

export const BoardRouters = [
  {
    path: '/board/list',
    name: 'BoardList',
    component: BoardList,
  },
  {
    path: '/board/detail',
    name: 'BoardDetail',
    component: BoardDetail,
  },
  {
    path: '/board/write',
    name: 'BoardWrite',
    component: BoardWrite,
  },
]

 

그리고 리스트 페이지에서 신규등록과 상세페이지 이동을 위한 함수를 아래와 같이 추가한다.

    fnGetList_not_paging() {
        ... 중략
    },
    fnView(boardNo) {
      this.requestBody.boardNo = boardNo
      this.$router.push({
        path : './detail',
        query: this.requestBody
      })
    },
    fnWrite() {
      this.$router.push({
        path : './write'
      })
    },
    fnPage(n) {
        ...중략
    }

 

그리고 화면 스타일을 공통 css로 옮기고 전체에서 같이 사용할 수 있도록 import 시키겠다. 

우선 게시판 관련 한 스타일을 /asset/board.css 파일을 생성한 뒤에 아래와 같이 스타일을 추가한다.

/* board.css */
.board-list {
    width: 80%;
    margin: auto;
}

.board-detail {
    width: 80%;
    margin: auto;
    text-align: left;
}

.board-content {
    padding: 8px 8px;
    border-bottom: 1px solid #eee;
}

.common-buttons {
    padding: 8px;
    text-align: right;
}

그리고 이 css를 전체적으로 사용하도록 main.js 상단에 import 시킨다.

import './assets/board.css' 

import { createApp } from 'vue'
import App from './App.vue'

그리고 기존에 boardList.vue 파일에서 개별 스타일 부여한 부분을 아래와 같이 수정한다.

<template>
  <div class="board-list">
    <div class="common-buttons">
      <button type="button" class="w3-button w3-round w3-blue-gray" v-on:click="fnWrite">등록</button>
    </div>
    ...생략
</template>

 

 

1. 신규 등록 파일을 아래와 같이 추가한다.

    boardWrite.vue

<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-content">
      <input type="text" v-model="title" class="w3-input w3-border" placeholder="제목을 입력해주세요.">
      <input type="text" v-model="writer" class="w3-input w3-border" placeholder="작성자를 입력해주세요." v-if="boardNo === undefined">
    </div>
    <div class="board-content">
      <textarea id="" cols="30" rows="10" v-model="content" 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,
      boardNo : this.$route.query.boardNo,

      title : '',
      content : '',
      writer : '',
      reg_date : '',
    }
  }, 
  mounted() {
    this.fnGetView()
  },
  methods: {
    fnGetView() {

      if (this.boardNo !== undefined) {

        this.$axios.get(this.$serverUrl + '/board/' + this.boardNo, {
          params : this.requestBody,
        }).then((res) => {
          this.title = res.data.title
          this.writer = res.data.writer
          this.content = res.data.content
          this.reg_date = res.data.reg_date
        })
        .catch((err) => {
          if (err.message.indexOf('Network Error') > -1) {
            alert('네트워크가 원활하지 않습니다.\n잠시 후 다시 시도해주세요.')
          }
        })
      }
    },

    fnList() {

      delete this.requestBody.boardNo
      this.$router.push({
          path: './list',
          query: this.requestBody
        }
      )
    },

    fnView(boardNo) {
      this.requestBody.boardNo = boardNo
      this.$router.push({
          path: './detail',
          query: this.requestBody
        }
      )
    },

    fnSave() {
      if(!confirm('저장하시겠습니까?')) return

      let apiUrl = this.$serverUrl + '/board'
      this.form = {
        //"boardNo": this.boardNo,
        "board_no": this.boardNo,
        "title": this.title,
        "writer": this.writer,
        "content": this.content,
      }

      if (this.boardNo === undefined) {
        //INSERT
        this.$axios.post(apiUrl, this.form)
          .then((res) => {
            alert('정상적으로 저장되었습니다.')
            this.fnView(res.data.board_no);
          })
          .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.board_no);
          })
          .catch((err) => {
            if (err.message.indexOf('Network Error') > -1) {
              alert('네트워크가 원활하지 않습니다.\n잠시 후 다시 시도해주세요.')
            }
          })
      }
    }
  }
}
</script>

여기서 주의할 점은 파라미터로 움직이는 부분의 키부분은 boardNo 로 주고 받지만 

데이터 베이스에서 주고 받는 것은 데이터 필드 그대로의 board_no 이름으로 리턴이 된다. 

다른 항목들도 마찬가지이다.

(예시,  변수 : boardNo/regDate,  전송/수신 : "board_no" / res.data.board_no / res.data.reg_date)

 

2. 상세보기 파일을 아래와 같이 추가한다.

    boardDetail.vue

<template>
  <div class="board-detail">
    <div class="common-buttons">
      <button type="button" class="w3-button w3-round w3-blue-gray" v-on:click="fnUpdate">수정</button>&nbsp;
      <button type="button" class="w3-button w3-round w3-red" v-on:click="fnDelete">삭제</button>&nbsp;
      <button type="button" class="w3-button w3-round w3-gray" v-on:click="fnList">목록</button>
    </div>
    <div class="board-content">
      <h3>{{ title }}</h3>
      <div>
        <strong class="w3-large">{{ writer }}</strong>
        <br>
        <span>{{ reg_date }}</span>
      </div>
    </div>
    <div class="board-content">
      <span>{{ content }}</span>
    </div>
    <div class="common-buttons">
      <button type="button" class="w3-button w3-round w3-blue-gray" v-on:click="fnUpdate">수정</button>&nbsp;
      <button type="button" class="w3-button w3-round w3-red" v-on:click="fnDelete">삭제</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,
      boardNo : this.$route.query.boardNo,

      title : '',
      content : '',
      writer : '',
      reg_date : '',
    }
  }, 
  mounted() {
    this.fnGetView()
  },
  methods: {
    fnGetView() {
      this.$axios.get(this.$serverUrl + '/board/' + this.boardNo, {
        params : this.requestBody,
      }).then((res) => {
        this.title = res.data.title
        this.writer = res.data.writer
        this.content = res.data.content
        this.reg_date = res.data.reg_date

      })
      .catch((err) => {
        if (err.message.indexOf('Network Error') > -1) {
          alert('네트워크가 원활하지 않습니다.\n잠시 후 다시 시도해주세요.')
        }
      })
    },

    fnList() {

      delete this.requestBody.boardNo
      this.$router.push({
          path: './list',
          query: this.requestBody
        }
      )
    },

    fnUpdate() {

      this.$router.push({
          path: './write',
          query: this.requestBody
        }
      )
    },

    fnDelete() {
      if(!confirm('삭제하시겠습니까?')) return

      this.$axios.delete(this.$serverUrl + '/board/' + this.boardNo, {})
        .then(() => {
          alert('정상적으로 삭제되었습니다.')
          
          this.fnList();
        })
        .catch((err) => {
            console.log(err)
        })
    }
  }
}
</script>

 

작성이 완료가 되었다면 서버를 기동하고 실행해보자

 

등록 버튼 클릭 후, 입력값을 넣고 저장하면 성공 메세지가 뜨고 상세페이지로 이동한다. 

수정버튼을 누르고 입력값을 변경하고 저장버튼을 누르면 성공 메세지가 뜨고 상세페이지로 이동한다.

삭제버튼을 누르고 확인을 누르면 정상적으로 삭제되었다고 메세지가 뜨고 리스트로 다시 이동한다.

 

게시판에 대한 기본적인 등록, 수정, 삭제를 완성하였다. 

다음 장에서는 첨부파일 처리에 대해서 진행해본다.

반응형

프로그램/Vue.js Related Articles

MORE

Comments