Vuex ToDoList sample
Vuex 및 bootstrap 을 활용한 할 일 목록 예제입니다
by plpot
HTML
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
<!-- Add this to <head> -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />
<!-- Add this after vue.js -->
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="app">
<todo-main></todo-main>
<div>
<todo-list></todo-list>
</div>
</div>
<template id="main">
<div class="border-bottom pt-4 pb-4">
<b-container>
<b-row class="text-center" align-v="center">
<b-col cols="2">할 일 : </b-col>
<b-col cols="8">
<b-form-input size="sm" v-model.trim="todoText" autofocus v-on:keyup.native.enter="saveTodo"></b-form-input>
</b-col>
<b-col cols="2">
<b-button v-bind:disabled="disabled" variant="success" size="sm" @click="saveTodo">추가</b-button>
</b-col>
</b-row>
</b-container>
</div>
</template>
<template id="todolist">
<div>
<b-container class="mt-3">
<b-form-radio-group v-model="condition">
<b-row>
<b-col>
<b-form-radio value="all">전체 할 일</b-form-radio>
</b-col>
<b-col>
<b-form-radio value="todo">남은 할 일</b-form-radio>
</b-col>
<b-col>
<b-form-radio value="done">끝난 할 일</b-form-radio>
</b-col>
</b-row>
</b-form-radio-group>
</b-container>
<b-list-group class="mt-3 ml-2 mr-2" v-if="todos.length === 0">
<b-list-group-item variant="secondary" class="mt-1">
<b-row class="text-center" align-v="center">
<b-col>
<span class="text-dark">할 일이 없습니다.</span>
</b-col>
</b-row>
...
Vue
const TodoMain = {
template: '#main',
data: function() {
return {
todoText: ''
}
},
methods: {
saveTodo: function(){
if(this.todoText != '')
this.$store.dispatch('saveTodo', this.todoText)
this.todoText = ''
}
},
computed: {
disabled () {
return this.todoText.trim().length === 0
}
}
}
const TodoList = {
template: '#todolist',
data: function() {
return {
condition: 'all',
selected: 0
}
},
methods: {
toggleTodo: function(id){
this.$store.dispatch('toggleTodo', id)
},
deleteConfirm: function(id){
this.selected = id
this.$refs.delConfirm.show()
},
deleteTodo: function(){
if(this.selected > 0){
this.$store.commit('deleteTodo', this.selected)
}
this.selected = 0
},
textClass: function(todo) {
return {
'text-dark': todo.done === false,
'text-danger': todo.done === true
}
}
},
computed: {
todos () {
switch(this.condition){
case 'todo':
return this.$store.state.todos.filter(todo => todo.done === false)
case 'done':
return this.$store.state.todos.filter(todo => todo.done === true)
}
return this.$store.state.todos
}
}
}
const store = new Vuex.Store({
state: {
id: 1,
todos: []
},
mutations: {
increment (state){
state.id++
},
deleteTodo (state, id) {
state.todos = state.todos.filter(todo => todo.id !== id)
}
},
actions: {
saveTodo (context, message) {
context.state.todos.push({
id: context.state.id,
text: message,
done: false
})
context.commit('increment')
},
toggleTodo (context, id) {
let todo = context.getters.getTodo(id)
todo.done = !todo.done
}
},
getters: {
getTodo: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
})
const app = new Vue({
el: '#app',
store,
components:...