본문 바로가기
Dev/Vue.js

[Vue.js] Today I Learned - 학습 노트 삭제

by dev_jsk 2020. 10. 28.
728x90
반응형

학습 노트 삭제

Today I Learned의 학습 노트를 삭제할 수 있는 기능을 구현한다.

삭제기능 마크업 및 이벤트 연결

삭제버튼을 구성하고 해당 버튼 클릭 시 이벤트가 발생하도록 연결한다.

<template>
  <li>
    <div class="post-title">
      {{ postItem.title }}
    </div>
    <div class="post-contents">
      {{ postItem.contents }}
    </div>
    <div class="post-time">
      {{ postItem.createdAt }}
      <!-- 수정, 삭제 아이콘 -->
      <i class="icon ion-md-create"></i>
      <!-- 클릭 시 deleteItem 이벤트 호출 -->
      <i class="icon ion-md-trash" @click="deleteItem"></i>
    </div>
  </li>
</template>

<script>
export default {
  props: {
    postItem: {
      type: Object,
      required: true,
    },
  },
  methods: {
    deleteItem() {
      console.log('delete');
    }
  }
};
</script>

삭제기능 구현

버튼 클릭 시 발생하는 이벤트를 구현한다. 추가적으로 삭제시 확인창과 삭제완료 후 목록 새로고침도 구현한다.

<!-- src/api/posts.js -->
<script>
// 학습 노트 조작과 관련된 CRUD API 함수 파일
import { posts } from './index';

// 학습 노트 데이터를 삭제하는 API
function deletePost(postId) {
  // axios.delete 사용하여 해당 학습 노트 고유 id 전달
  return posts.delete(postId);
}

export { deletePost };
</script>

<!-- src/components/posts/PostListItem.vue -->
<script>
import { deletePost } from '@/api/posts';

export default {
  props: {
    postItem: {
      type: Object,
      required: true,
    },
  },
  methods: {
    async deleteItem() {
      // 삭제 여부를 묻는 확인창
      if (confirm('You want to delete it?')) {
        // 해당 학습 노트의 고유 ID 값 전달
        await deletePost(this.postItem._id);
        // 삭제 후 MainPage.vue로 refresh 이벤트 전달
        // 해당 이벤트 전달하여 목록 새로고침
        this.$emit('refresh');
      }
    },
  },
};
</script>

<!-- scr/views/MainPage.vue -->
<template>
  <div>
    <div class="main list-container contents">
      <h1 class="page-header">Today I Learned</h1>
      <LoadingSpinner v-if="isLoading"></LoadingSpinner>
      <ul v-else>
        <!-- 하위 컴포넌트에서 전달받은 refresh 이벤트를 통해 fetchData 함수 호출 -->
        <!-- fetchData(): 목록 데이터 조회 함수 -->
        <PostListItem
          v-for="postItem in postItems"
          :key="postItem._id"
          :postItem="postItem"
          @refresh="fetchData"
        ></PostListItem>
      </ul>
    </div>
    <router-link to="/add" class="create-button">
      <i class="ion-md-add"></i>
    </router-link>
  </div>
</template>

<script>
import PostListItem from '@/components/posts/PostListItem.vue';
import LoadingSpinner from '@/components/common/LoadingSpinner.vue';
import { fetchPosts } from '@/api/posts';

export default {
  components: {
    PostListItem,
    LoadingSpinner,
  },
  data() {
    return {
      postItems: [],
      isLoading: false,
    };
  },
  methods: {
    // 목록 데이터 조회
    async fetchData() {
      this.isLoading = true;
      const { data } = await fetchPosts();
      this.isLoading = false;
      this.postItems = data.posts;
    },
  },
  created() {
    this.fetchData();
  },
};
</script>

학습 노트 생성 시 UX 개선

지금까지 학습 노트를 생성하고 계속 등록 페이지에 머물러 있는데 router.push()를 통해 생성 후 메인페이지로 이동하도록 구현하여 UX를 개선할 수 있다.

<!-- src/views/MainPage.vue -->
<script>
import { createPost } from '@/api/posts';

export default {
  data() {
    return {
      title: '',
      contents: '',
      logMessage: '',
    };
  },
  computed: {
    isContentsValid() {
      return this.contents.length <= 200;
    },
  },
  methods: {
    async submitForm() {
      try {
        const response = await createPost({
          title: this.title,
          contents: this.contents,
        });
        // 학습 노트 생성 후 push() 를 통해 메인 페이지로 이동
        this.$router.push('/main');
      } catch (error) {
        console.log(error.response.data.message);
        this.logMessage = error.response.data.message;
      }
    },
  },
};
</script>
728x90
반응형

댓글