새로운 강의는 이제 https://memi.dev 에서 진행합니다.
memi가 Vue & Firebase로 직접 만든 새로운 사이트를 소개합니다.

바로가기


모던웹(NEMV) 혼자 제작 하기 3기 - 71 게시판 내용 수정과 삭제

2 분 소요

선택된 게시물의 수정과 삭제를 구현해보겠습니다.

개요

CRUD 중 UD 부분을 마무리해봅니다.

게시판 아이디(board._id)는 필요가 없습니다.

게시물 아이디(article._id)만 필요합니다.

게시물 아이디를 선택해서 수정과 삭제를 하면 되는 것입니다.

구현하기

다이얼로그가 3개가 필요합니다.

  • 글 쓰기용
  • 글 읽기용
  • 글 수정용

3개를 다 따로 만들어도 되지만 코드가 지저분해져서 재활용 해봤습니다.(물론 3개 써도 크게 상관은 없습니다.)

fe/src/views/board/anyone.vue

<template>  
    <v-dialog v-model="dialog" persistent max-width="500px">
      <v-card v-if="!dlMode">
        <v-card-title>
          <span class="headline">{{selArticle.title}}</span>
        </v-card-title>
        <v-card-text>
          {{selArticle.content}}
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="warning darken-1" flat @click.native="modDialog()">수정</v-btn>
          <v-btn color="error darken-1" flat @click.native="ca=true">삭제</v-btn>
          <v-btn color="secondary darken-1" flat @click.native="dialog = false">닫기</v-btn>
        </v-card-actions>
        <v-card-text>
          <v-card-text v-if="ca">
            <v-alert v-model="ca" type="warning">
              <h4>정말 진행 하시겠습니까?</h4>
              <v-btn color="error" @click="del()">확인</v-btn>
              <v-btn color="secondary" @click="ca=false">취소</v-btn>
            </v-alert>
          </v-card-text>
        </v-card-text>
      </v-card>
      <v-card v-else>
        <v-card-title>
          <span class="headline">{{(dlMode === 1) ? '작성' : '수정'}}</span>
        </v-card-title>
        <v-card-text>
          <v-container grid-list-md>
            <v-layout wrap>
              <v-flex xs12>
                <v-text-field
                  label="제목"
                  persistent-hint
                  required
                  v-model="form.title"
                ></v-text-field>
              </v-flex>
              <v-flex xs12>
                <v-textarea
                  label="내용"
                  persistent-hint
                  required
                  v-model="form.content"
                ></v-textarea>
              </v-flex>
            </v-layout>
          </v-container>
        </v-card-text>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="green darken-1" flat @click="(dlMode === 1) ? add() : mod()">확인</v-btn>
          <v-btn color="red darken-1" flat @click.native="dialog = false">취소</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
</template>
<script>
import boardCard from '@/components/manage/boardCard'

export default {
  components: { boardCard },
  data () {
    return {
      // ..
      dlMode: 0, // 0: read, 1: write, 2: modify
      selArticle: {},
      ca: false
    }
  },
  // ..
  methods: {
    addDialog () {
      this.dialog = true
      this.dlMode = 1
      this.form = {
        title: '',
        content: ''
      }
    },
    modDialog () {
      this.dlMode = 2
      this.form = {
        title: this.selArticle.title,
        content: this.selArticle.content
      }
    },
    // ..
    read (atc) {
      this.selArticle = atc
      this.loading = true
      this.$axios.get(`article/read/${atc._id}`)
        .then(({ data }) => {
          if (!data.success) throw new Error(data.msg)
          this.dlMode = 0
          this.dialog = true
          this.selArticle.content = data.d.content
          this.selArticle.cnt.view = data.d.cnt.view
          this.loading = false
        })
        .catch((e) => {
          this.pop(e.message, 'error')
          this.loading = false
        })
    },
    mod () {
      if (!this.form.title) return this.pop('제목을 작성해주세요', 'warning')
      if (!this.form.content) return this.pop('내용을 작성해주세요', 'warning')
      if (this.selArticle.title === this.form.title && this.selArticle.content === this.form.content)
        return this.pop('변경된 내용이 없습니다', 'warning')
      this.$axios.put(`article/${this.selArticle._id}`, this.form)
        .then(({ data }) => {
          this.dialog = false
          if (!data.success) throw new Error(data.msg)
          this.selArticle.title = data.d.title
          this.selArticle.content = data.d.content
          // this.list()
        })
        .catch((e) => {
          this.pop(e.message, 'error')
        })
    },
    del () {
      this.$axios.delete(`article/${this.selArticle._id}`)
        .then(({ data }) => {
          this.dialog = false
          if (!data.success) throw new Error(data.msg)
          this.list()
        })
        .catch((e) => {
          this.pop(e.message, 'error')
        })
    },
    // ..
  }
}
</script>
  • dlMode(0: 읽기, 1: 쓰기, 2: 수정)로 다이얼로그를 재활용 했습니다.
  • 삭제는 위험하기 때문에 확인창(v-alert)를 추가했습니다.
  • 읽거나(read()) 수정 후(mod()) 불필요하게 리스트를 갱신하지 않고 해당 값만 취했습니다.

결과

다이얼로그 읽기
alt read 다이얼로그 수정
alt modify 다이얼로그 삭제
alt delete

소스

소스 확인

영상

댓글남기기