Laravelで作ったAPI(前回の続き)から受け取ったJSONデータをVueを使ったtodoリストで描画する
ここで作るtodoリストに変更を加えていく。
Vue.jsミニハンズオン(TODOリスト作成) - Qiita
オリジナルでは、 todoをlocalStrageに保存しているが、DBに保存するようにする。
まず、jsを移植する。
// todo-app/resources/assets/js/app.js window.Vue = require('vue'); +Vue.prototype.$http = window.axios + /** * Next, we will create a fresh Vue application instance and attach it to * the page. Then, you may begin adding components to this application * or customize the JavaScript scaffolding to fit your unique needs. */ -Vue.component('example-component', require('./components/ExampleComponent.vue')); +Vue.component('todo-item', { + props: ['name', 'is_done', 'id'], + template: ` + <li class="list-complete-item"> + <label v-bind:class="{ done: is_done }"> + <input type="checkbox" v-model="childisChecked" v-on:change="deleteCheck"> {{ name }} + </label> + </li>`, + data: function () { + return { + childisChecked: this.is_done + } + }, + methods: { + deleteCheck: function () { + this.$emit('delete', this.childisChecked, this.id) + } + } +}) -const app = new Vue({ - el: '#app' -}); +const vm = new Vue({ + el: '#app', + data: { + items: [], + newItemTitle: '', + }, + methods: { + loadTodo: function() { + this.$http.get('/api/tasks') + .then(res => { + this.items = res.data + }) + }, + addTodo: function(newTitle) { + this.$http.post('/api/tasks', { name: newTitle, is_done: false }) + .then(res => { + this.items.push({ + name: res.data.name, + is_done: res.data.is_done, + id: res.data.id + }); + this.newItemTitle = ''; + }) + }, + deleteTodo: function() { + let self = this; + this.items = this.items.filter(function (item) { + if ( item.is_done === true ) { + self.$http.delete('/api/tasks/' + item.id) + .then(res => { + }) + } + return item.is_done === false; + }); + }, + updateCheck: function(childChecked, childIndex) { + for (let i = 0; i < this.items.length; i++) { + if (this.items[i].id === childIndex) { + this.items[i].is_done = childChecked; + break; + } + } + } + }, + mounted: function() { + this.loadTodo(); + } +}) \ No newline at end of file
次にapp.bladeを移植する。
// todo-app/resources/views/app.blade.php <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="csrf-token" content="{{ csrf_token() }}"> + <title>Laravel</title> + <link rel="stylesheet" href="css/app.css"> + <style> + .done { + text-decoration: line-through; + } + .list-complete-item { + transition: all 1s; + } + .list-complete-enter, .list-complete-leave-to { + opacity: 0; + transform: translateX(30px); + } + .list-complete-leave-active { + position: absolute; + } + </style> </head> <body> <div id="app"> - <example-component></example-component> + <p> + <input type="text" placeholder="add todo item" v-model="newItemTitle" v-on:keyup.enter="addTodo(newItemTitle)"> + </p> + <transition-group name="list-complete" tag="ul"> + <todo-item v-for="item in items" v-bind="item" v-bind:key="item.id" v-on:delete="updateCheck"></todo-item> + </transition-group> + <button v-on:click="deleteTodo()">Delete</button> </div> + <script src="js/app.js"></script> </body> </html>
ビルドする。
npm run dev