본문 바로가기

Programming/Vue

Vue todolist 만들기 - 8. Backend 연동을 위해 Frontend 수정하기

반응형

1. store/store.js 수정
store.js 파일에 url request가 가능하도록 각 기능마다 axios 기능을 추가해줍니다. 아울러, 최초 Load시에는 DB의 정보들을 불러올 수 있도록 onLoad함수를 추가해주었습니다.

import { createStore } from 'vuex';
import axios from 'axios';

axios.defaults.baseURL = 'http://localhost:3000';
axios.defaults.headers.post['Content-Type']='application/json;charset=utf-8';
axios.defaults.headers.post['Access-Control-Allow-Origin']='*';

export const store = createStore({
// export default createStore({
  state:{
    user:{
      // {username: '홍길동', email: 'abcd@abcd.com', password: '1234'}
    },
    posts: [
      // {_id: '1', title: 'apple', body: 'Im apple', creator: 'apple'},
      // {_id: '2', title: 'banana', body: 'Im banana', creator: 'banana'},
      // {_id: '3', title: 'orange', body: 'Im orange', creator: 'orange'}
    ]
  },
  mutations:{
    updateState(state, payload) {
      Object.keys(payload).forEach((key) => {
        state[key] = payload[key];        
      });
    },
    LOGIN(state, payload){
      state.user = payload;
    },
    DELETEPOST(state, post_id){            
      const delete_index = state.posts.findIndex(p=> p._id === post_id);      // 삭제할 포스트의 index 찾기
      state.posts.splice(delete_index,1);      
    },
    UPDATEPOST(state,updatePost){      
      const update_store_item = state.posts.find(p => p._id === updatePost._id);      
      // console.log(updatePost)
      update_store_item.title = updatePost.title;
      update_store_item.body = updatePost.body;
    }
  },
  actions:{ 
    async login(context, name){            
      const res = await axios.post('/auth/register',name);      
      context.commit('LOGIN', res.data);
    },  
    async onLoad(context){
      const res = await axios.get('/posts');
      const { post } = res.data;
      console.log(post);
      context.commit("updateState", {
        posts: [...context.state.posts, ...post],
      })
    },
    async addPost(context, newPost){
      // const id= context.state.posts.length+1;      
      // const post={
      //   _id: id,
      //   title: newPost.title,
      //   body: newPost.body,
      //   creator: newPost.title
      // }
      const res = await axios.post('/posts', newPost);
      const post = res.data;  
      context.commit("updateState", {
        posts: [...context.state.posts, post],
      })         
    },
    async deletePost(context, post_id){
      await axios.delete(`/posts/${post_id}`);  
      context.commit("DELETEPOST", post_id);
    } ,
    async updatePost(context, updatePost){
      const { _id } = updatePost;
      await axios.patch(`/posts/${_id}`, updatePost);
      context.commit("UPDATEPOST", updatePost)
    }    
  }
});

 
2. view/HomeView.vue 수정
유저가 존재할 경우와 존재하지 않을 경우를 구분하여 표시하도록 파일을 수정해줍니다.

<template>
  <div class="logincheck">
    <div v-if="isloggedin">안녕하세요, {{ user.username }}님</div>    
    <router-link to="/kakaologin" v-else>Kakao Login</router-link>
  </div> 
  <h1 class="appname">My Todo App</h1>  
  <AddPost />
  <ListofPost />
</template>

<script>
import ListofPost from '../components/ListofPost.vue'
import AddPost from '../components/AddPost.vue'

export default {
  name: 'HomeView',
  components: {
    ListofPost,
    AddPost,
  },
  computed:{
    user(){
      return this.$store.state.user
    },
    isloggedin(){
      return this.$store.state.user.username? true : false;
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;  
  color: #2c3e50;
  margin-top: 60px;  
}
.appname {
  color:#373738;
  text-align: center;
}
.addbutton{
  margin: auto;
  display:flex;
  align-items:center;
  justify-content: center;
  width:50px;
  height:50px;  
  border-radius: 50%;
  background-color:blue ; 
  font-size: 36px;
  font-weight: bold;
  color:beige;
}
.logincheck{  
  text-align: right;  
  margin-right: 15px;
}
</style>

 
3. components/ListofPost.vue 수정
최초 로딩시 DB 데이터를 불러오도록 onLoad 함수를 호출합니다.

<template>
  <ul>
    <li v-for="post in posts.slice().reverse()" :key=post>
      <EachofPost 
        :id=post._id
        :titleOfPost=post.title 
        :bodyOfPost=post.body 
        :creator=post.creator />
    </li>
  </ul>
</template>
<script>
import EachofPost from './EachofPost.vue'

export default {
  name: 'ListofPost',
  components: {
    EachofPost,
  },
  computed:{
    posts(){
      return this.$store.state.posts;
    },    
  }, 
  created(){
      this.$store.dispatch('onLoad');  // 추가
  }
}
</script>

<style>
ul{
  padding-left:0;
}
li{
  list-style: none;
}
</style>

 

반응형