반응형
Store를 적용해보겠습니다.
npm i vuex axios // axios는 나중에 backend 통신을 위해 미리 설치
1. store/store.js
기본 post 리스트를 생성하고, 포스트 추가/삭제기능을 구현해놓는다. 기능은 추후 Backend와의 연동을 위해 actions에 구현해놓습니다.
import { createStore } from 'vuex';
// import axios from 'axios';
export const store = createStore({
// export default createStore({
state:{
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];
});
},
DELETEPOST(state, post_id){
const delete_index = state.posts.findIndex(p=> p._id === post_id); // 삭제할 포스트의 index 찾기
state.posts.splice(delete_index,1);
},
},
actions:{
addPost(context, newPost){
const id= context.state.posts.length+1;
const post={
_id: id,
title: newPost.title,
body: newPost.body,
creator: newPost.title
}
context.commit("updateState", {
posts: [...context.state.posts, post],
})
// console.log(context.state.user)
},
deletePost(context, post_id){
context.commit("DELETEPOST", post_id);
}
}
});
2. main.js 수정
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { store } from './store/store.js' // 추가
createApp(App)
.use(router)
.use(store) // 추가
.mount('#app')
3. components/ListofPost.vue수정
<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;
}
}
// 여기까지 추가, 아래는 주석 or 삭제
// data(){
// return {
// posts: [
// {
// _id:1,
// title: 'myPost',
// body: 'My Post 1',
// creator: 'apple'
// },
// {
// _id:2,
// title: 'myPost2',
// body: 'My Post 2',
// creator: 'banana'
// }
// ]
// }
// }
// }
}
</script>
<style>
ul{
padding-left:0;
}
li{
list-style: none;
}
</style>
4. components/AddPost.vue
포스트를 추가하는 기능을 구현합니다. 편의상 작성자는 title과 동일하게 가져가겠습니다.
<template>
<div class="new_post">
<div class="new_post_header">
<input type="text" name="title" v-model="title" class="title"/>
<input type="submit" value="Add" @click="addPost" class="submit">
</div>
<div class="new_post_body">
<textarea class="contents" name="body" v-model="body" />
</div>
</div>
</template>
<script>
export default {
data(){
return {
title:'제목',
body:'내용',
};
},
methods:{
addPost(){
this.$store.dispatch('addPost',{
title: this.title,
body: this.body,
creator: this.title,
})
}
}
}
</script>
<style>
.new_post{
background-color:#E0EDFB;
/* margin: 5px auto; */
border: 1px solid grey;
border-radius: 10px;
box-sizing: content-box;
width:100%;
}
.new_post .new_post_header{
display: flex;
padding: 5px;
}
.new_post .new_post_header .title{
display:inline-block;
text-align: left;
font-size: 24px;
height: 50px;
width:100%;
color: black;
border: 0px solid black;
background-color:transparent;
}
.new_post .new_post_header .submit{
position: relative;
font-size:20px;
color:dimgrey;
background-color: transparent;
border-color: transparent;
}
.new_post .new_post_body{
position: relative;
font-size: 16px;
color:cadetblue;
text-align: left;
/* padding: 5px; */
}
.new_post .new_post_body .contents{
position: relative;
border: 0px;
left:0;
right:0;
margin: 5px;
width:99%;
box-sizing: border-box;
background-color:transparent;
}
</style>
5. components/EachofPost.vue
포스트를 삭제하는 기능을 구현합니다.
<template>
<div class="post">
<div class="post_header">
<div class="title">
{{ id }}
{{ titleOfPost }}
</div>
<button class="close" @click="removeItem">x</button>
</div>
<div class="post_body">
{{ bodyOfPost }}
<div class="creator">
by {{ creator }}
</div>
</div>
</div>
</template>
<script>
export default {
props:['id','titleOfPost', 'bodyOfPost','creator'],
// 아래 추가
methods:{
removeItem(){
this.$store.dispatch("deletePost", this.id)
}
}
// 여기까지 추가부분
}
</script>
<style>
.post{
/* background-color:blanchedalmond; */
margin: 5px auto;
border: 1px solid grey;
border-radius: 10px;
width:100%;
min-height:100px;
}
.post .post_header{
display: flex;
padding: 5px;
}
.post .post_header .title{
display:inline-block;
text-align: left;
font-size: 24px;
height: 50px;
width:100%;
color: black;
border: 0px solid;
/* background-color:blueviolet; */
}
.post .post_header .close{
position: relative;
font-size:20px;
width:20px;
height:20px;
color:dimgrey;
background-color: transparent;
border-color: transparent;
}
.post .post_header .edit{
position: relative;
box-sizing: border-box;
font-size:20px;
width:20px;
height:20px;
color:dimgrey;
background-color: transparent;
border-color: transparent;
}
.post .post_body{
font-size: 16px;
color:cadetblue;
text-align: left;
padding: 5px;
border: 0px solid;
/* background-color: orange; */
width: 100%;
min-height: 25px;
}
.post .post_body .creator{
text-align: right;
left:0;
right: 0;
top: 0;
bottom: 0;
margin-right: 10px;
margin-bottom: 5px;
/* right: 10px; */
}
.post .post_body textarea{
width: 95%;
min-height:24px;
border: 0px;
font-size: 16px;
color:cadetblue;
}
</style>
반응형
'Programming > Vue' 카테고리의 다른 글
Vue todolist 만들기 - 6. Kakao 로그인 구현 (0) | 2023.05.04 |
---|---|
Vue todolist 만들기 - 5. Post 수정기능 (0) | 2023.05.04 |
Vue todolist 만들기 - 3. Vue 프로젝트 상세구성 (0) | 2023.05.04 |
Vue todolist 만들기 - 2. Vue 프로젝트 만들기 (0) | 2023.05.04 |
Vue todolist 만들기 - 1. 환경세팅 (0) | 2023.05.04 |