プログラミング

Nuxt.jsで作成したtodoアプリの解説

こちらの記事を元に作成し、自分なりに解説を加えました。

追加機能について

store/index.js

/* eslint-disable eqeqeq */
import Vuex from 'vuex'

const createStore = () => {
return new Vuex.Store({
state: () => ({
todos: [
// todosに対して、値を保持する。
]
}),
mutations: {
insert (state, obj) { // mutations内の関数の第一引数にはstateをとるのがルール。第二引数には関数内で使用するためのなんでも良い引数をつける。
const d = new Date()
const fmt = d.getFullYear() +
'-' + ('00' + (d.getMonth() + 1)).slice(-2) +
'-' + ('00' + d.getDate()).slice(-2) +
' ' + ('00' + d.getHours()).slice(-2) +
':' + ('00' + d.getMinutes()).slice(-2)
state.todos.unshift({ // state.todosでVuex.Store内の配列todosにアクセスしunshiftでpages/index.vueで渡されたthis.content、unshif内では第二引数.contentと作成した日時、mftを追加する。
content: obj.content,
created: fmt
})
},
remove (state, obj) {
for (let i = 0; i < state.todos.length; i++) {
const ob = state.todos[i]
if (ob.content == obj.content && ob.created == obj.created) {
alert('remove ' + '"' + ob.content + '"')
state.todos.splice(i, 1)
return
}
}
}
}
})
}

export default createStore

 

 

pages/index.vue

<template>
<section class="container">
<h1>Todo App</h1>
<p><input v-model="content" type="text" name="content"></p>
<div>
<button @click="insert">
save
</button>
<button>find</button>
</div>
<ul>
<li v-for="(todo, index) in todos" :key="index">
<span>{{ todo.content }}</span><span>({{ todo.created }})</span><span>×</span>
</li>
</ul>
</section>
</template>

<script>
import { mapState } from 'vuex'

export default {
data () {
return {
content: ''
}
},
computed: {
...mapState(['todos'])// mapState({ todos: this.$store.state.todos})と同じ
},
methods: {
insert () {
this.$store.commit('insert', { content: this.content })// store/index.jsのmutationsのinsert関数に送る。this.$store.commit('insert', { content: this.content })でmutationを実行できる。第一引数の'insert'がindex.jsのstate、第二引数のthis,contentがindex.jsのobjになる。
this.content = ''// 実行したらcontentを空白にする。
}
}
}
</script>

 

検索機能について

pages/index.vue

 

<template>
<section class="container">
<h1>Todo App</h1>
<p><input type="text" name="content" v-model="content" @focus="set_flg"/></p>
<div>
<button @click="insert">save</button>
<button @click="find">find</button>
</div>
<ul>
<li v-for="(todo, index) in display_todos" :key="index">
<span>{{ todo.content }}</span><span>({{ todo.created }})</span><span>×</span>
</li>
</ul>
</section>
</template>

<script>
import {mapState} from 'vuex';

export default {
data: function() {
return {
content: '',
find_flg: false
}
},
computed: {
...mapState(['todos']),
display_todos: function() {
if(this.find_flg) {
var arr = [];
var data = this.todos;
data.forEach(element => { //dataとthis.todosとelementは同じ値を持つ。
if(element.content.toLowerCase() == this.content.toLowerCase()) {//computed内のMapstate内で'todos'を定義しているので、store/index.js内のtodosはthis.todosで呼び出せる。 入力されたtodoがtodosの中にあれば
arr.push(element); //arrに追加する
}
});
return arr; //arrを表示する
} else {
return this.todos; //contentに入力された値とsotre/index.js内の値に一致するものがなければstore/index.js内の値全て、つまりthis.todosを表示する。
}
}
},
methods: {
insert: function() {
this.$store.commit('insert', {content: this.content});
this.content = '';
},
find: function() {
this.find_flg = true;
},
set_flg: function() {
if(this.find_flg) {
this.find_flg = false;
this.content = '';
}
},
}
}
</script>