vue.js/vue.js 2

130. posts 수정 API 구현 | this.$route.params.id | Dynamic Route Matching 사용

DEV-Front 2023. 2. 19. 17:42
반응형

0. router에 path: '/post/:id' 추가

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

export default new VueRouter({
  mode: 'history',
  routes: [
    {
      path: '/',
      redirect: '/login',
    },
    {
      path: '/login',
      component: () => import('@/views/LoginPage.vue'),
    },
    {
      path: '/signup',
      component: () => import('@/views/SignupPage.vue'),
    },
    {
      path: '/main',
      component: () => import('@/views/MainPage.vue'),
    },
    {
      path: '/add',
      component: () => import('@/views/PostAddPage.vue'),
    },
    {
      path: '/post/:id',
      component: () => import('@/views/PostEditPage.vue'),
    },
    {
      path: '*',
      component: () => import('@/views/NotFoundPage.vue'),
    },
  ],
});

1. PostListItem.vue

- 학습목록 list에 수정 아이콘 추가

- @click="routerEditPage" 이벤트 구현

- this.$router.push(`/post/${this.postItem._id}`);

<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" @click="routerEditPage"></i>
      <i class="icon ion-md-trash" @click="deleteItem"></i>
    </div>
  </li>
</template>

<script>
import { deletePost } from '@/api/posts';

export default {
  props: {
    postItem: {
      type: Object,
      required: true,
    },
  },
  methods: {
    async deleteItem() {
      if (confirm('You want to delete it?')) {
        await deletePost(this.postItem._id);
        this.$emit('refresh');
      }
      // console.log('deleted');
    },
    routerEditPage() {
      this.$router.push(`/post/${this.postItem._id}`);
    },
  },
};
</script>

<style></style>

2. api/index.js 

- 특정학습 노트 1개를 조회 API 추가

- 학습 노트 데이터를 수정하는 API 추가

// 학습 노트 조작과 관련된 CRUD API 함수 파일
import { posts } from './index';

// 학습 노트 데이터 목록을 조회하는 API
function fetchPosts() {
  return posts.get('/');
}

// 특정학습 노트 1개를 조회 API
function fetchPost(postId) {
  return posts.get(postId);
}

// 학습 노트 데이터를 생성하는 API
function createPost(postData) {
  return posts.post('/', postData);
}

// 학습 노트 데이터를 삭제하는 API
function deletePost(postId) {
  return posts.delete(postId);
}

// 학습 노트 데이터를 수정하는 API
function editPost(postId, postData) {
  return posts.put(postId, postData);
}

export { fetchPosts, createPost, deletePost, fetchPost, editPost };

3. PostEditPage.vue 생성

<template>
  <div>
    <PostEditForm />
  </div>
</template>

<script>
import PostEditForm from '@/components/posts/PostEditForm.vue';
export default {
  components: {
    PostEditForm,
  },
  data() {
    return {};
  },

  mounted() {},

  methods: {},
};
</script>

<style lang="scss" scoped></style>

4. PostEditForm.vue 생성

- 컴포넌트 생성과 동시에 id에 해당하는 title, contentes Data 바인딩

- Update 버튼 click 시 this.$route.params.id와 수정할 title, contents 보내기 

<template>
  <div class="contents">
    <h1 class="page-header">Edit Post</h1>
    <div class="form-wrapper">
      <form class="form" @submit.prevent="submitForm">
        <div>
          <label for="title">Title:</label>
          <input id="title" type="text" v-model="title" />
        </div>
        <div>
          <label for="contents">Contents:</label>
          <textarea id="contents" type="text" rows="5" v-model="contents" />
          <p
            v-if="!isContentsValid"
            class="validation-text warning isContentTooLong"
          >
            Contents length must be less than 250
          </p>
        </div>
        <button type="submit" class="btn">Update</button>
      </form>
      <p class="log">
        {{ logMessage }}
      </p>
    </div>
  </div>
</template>

<script>
import { fetchPost, editPost } from '@/api/posts';

export default {
  data() {
    return {
      title: '',
      contents: '',
      logMessage: '',
    };
  },
  computed: {
    isContentsValid() {
      return this.contents.length <= 200;
    },
  },
  async created() {
    // 컴포넌트 생성과 동시에 id에 해당하는 title, contentes Data 바인딩
    const { data } = await fetchPost(this.$route.params.id);
    this.title = data.title;
    this.contents = data.contents;
    console.log(data);
  },
  methods: {
    async submitForm() {
      // Update 버튼 click 시 this.$route.params.id와 수정할 title, contents 보내기 
      try {
        const response = await editPost(this.$route.params.id, {
          title: this.title,
          contents: this.contents,
        });
        this.$router.push('/main');
        console.log(response);
      } catch (error) {
        console.log(error.response.data.message);
        this.logMessage = error.response.data.message;
      }
    },
  },
};
</script>

<style scoped>
.form-wrapper .form {
  width: 100%;
}

.btn {
  color: white;
}
</style>

반응형