티스토리 뷰
728x90
지난 글에 이어 이번에는 수정 기능을 추가했다. 😀
할 일 목록을 추가할 때와 수정할 때 폼이 동일해서 TodoInpuForm이라는 컴포넌트로 분리했고 추가, 수정 함수를 callback props로 받았다. 추가, 수정일 때 버튼의 문자도 다르게 노출시켰다. 수정 일 때는 입력한 텍스트를 노출해야 하기 때문에 옵션으로 기본 텍스트 값을 추가했다.
// TodoInputForm.vue
<template>
<div>
<input v-model="input" type="text" @keyup="keyupInput">
<button type="button" @click="updateTodo">
{{ mode === 'add' ? 'ADD' : 'EDIT' }}
</button>
</div>
</template>
<script>
export default {
props: {
callback: {
type: Function,
required: true
},
mode: {
type: String,
default: 'add'
},
defaultText: {
type: String,
default: '',
required: false
}
},
data () {
return {
input: this.defaultText
}
},
methods: {
updateTodo () {
if (this.input.trim() === '') { return }
this.callback(this.input)
},
keyupInput (event) {
if (event.key !== 'Enter') { return }
this.updateTodo(this.input)
}
}
}
</script>
할 일을 추가할 때는 defaultText가 필요하지 않기 때문에 props를 생략했고 수정할 때는 defaultText를 props로 전달했다.
// pages/create.vue
<template>
<div>
<h1>Create Todo</h1>
<todo-input-form :callback="add" :mode="`add`" />
</div>
</template>
<script>
import { mapActions } from 'vuex'
import TodoInputForm from '~/components/TodoInputForm'
export default {
components: {
TodoInputForm
},
methods: {
add (input) {
this.createTodo(input)
// redirect list
this.$router.push('/')
},
...mapActions(['createTodo'])
}
}
</script>
// pages/edit.vue
<template>
<div>
<h1>Edit Todo</h1>
<todo-input-form :callback="edit" :mode="`edit`" :default-text="selectedTodo && selectedTodo.text" />
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
import TodoInputForm from '~/components/TodoInputForm'
export default {
components: {
TodoInputForm
},
computed: {
...mapState({ selectedTodo: state => state.selectedTodo })
},
methods: {
edit (input) {
this.editTodo(input)
// redirect list
this.$router.push('/')
},
...mapActions(['editTodo'])
}
}
</script>
UI는 동일하고 기능만 다르기 때문에 분리한 컴포넌트를 추가하고 actions에서 구현한 기능을 가져와 그대로 사용했다.
// pages/index.vue
<template>
<div id="app">
<ul>
<li v-for="todo in todos" :key="todo.id">
<input :checked="todo.completed" type="checkbox" @change="toggleTodo(todo.id)">
<nuxt-link :to="`/todo/${todo.id}`">
<span @click="setTodo(todo)">{{ todo.text }}</span>
</nuxt-link>
<button type="button" @click.prevent="removeTodo(todo.id)">
delete
</button>
<nuxt-link :to="`/todo/edit`">
<button type="button" @click="setTodo(todo)">
edit
</button>
</nuxt-link>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
methods: {
...mapActions(['removeTodo', 'toggleTodo', 'setTodo'])
},
computed: {
...mapGetters({
todos: 'getFilteredTodos'
})
}
}
</script>
<style scoped>
ul{padding:0px}
li{list-style:none}
</style>
edit 버튼을 추가하고 nuxt-link로 연결했다. edit 버튼을 클릭하면 선택한 할 일 목록을 vuex에 담고 가져다 쓰도록 했다. id 기반으로 동작하는 방법으로 구현도 가능하시만 쉽게 할 요령으로 간단히 구현했다.
아래는 최종 결과 화면이다.
다음 시간에는 axio로 데이터를 API로 가져오고, 추가하고, 수정하고 삭제하는 기능을 구현할 예정이다.
도움이 되셨다면 공감❤️ 눌러주세요.
728x90
댓글