Learning Vuejs 4

Creating the Todo add form and Interactions between Components

HTML

<script src="https://vuejs.org/js/vue.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.28/vue.min.js"></script>
<div class="container" id="vue-app">
  <div class="row">
    <div class="col-sm-12">
      <h1>My Todos</h1>
      <todo-item :todos="todos"></todo-item>
      
      <todo-add-form :newtodo.sync="newTodo"></todo-add-form>
    </div>
  </div>
  
  <template id="todo-list-template">
    <div>
      <ul class="list-group">
        <li 
          v-for="todo in todos"
          class="list-group-item"
          v-bind:class="{ 'completed' : todo.completed }">
            {{todo.title}}
            <button class="btn btn-xs pull-right margin-right-10" 
            v-bind:class="{'btn-success' : todo.completed, 'btn-danger' : !todo.completed}"
            v-on:click="todoCompleted(todo)">{{todo.completed ? 'Completed' : 'Pending'}}</button>
          </li>
      </ul>
    </div>
  </template>
  
  <template id="todo-add-form">
    <form v-on:submit.prevent="addTodo()">
      <div class="form-group">
        <input type="text" class="form-control" placeholder="Enter new Todo" v-model="todo.title">
      </div>
      
      <div class="form-group">
        <button class="btn btn-success">Add</button>
      </div>
    </form>
  </template>
</div>

CSS

li.completed {
  text-decoration: line-through;
}

JavaScript

var TodoItems = Vue.extend({
	template: '#todo-list-template',
  
  props: ['todos'],
  
  methods: {
  	todoCompleted(todo) {
    	todo.completed = !todo.completed
    }
  }
});

var TodoAddForm = Vue.extend({
	template: '#todo-add-form',
  
  props: ['newtodo'],
  
  data() {
  	return {
    	todo: {id: null, title: '', completed: false}
    }
  },
  
  methods: {
  	addTodo() {
    	this.newtodo = this.todo;
      this.todo = {id: null, title: '', completed: false};
    }
  }
});

Vue.component('todo-item', TodoItems);
Vue.component('todo-add-form', TodoAddForm);

new Vue({
	el: '#vue-app',
  
  data: {
  	todos: [{id: 1, title: 'Go Shopping', completed: true}],
    newTodo: {}
  },
  
  watch: {
  	newTodo(newval, oldval) {
    	this.todos.push({
      	id: Math.floor(Date.now()),
        title: newval.title,
        completed: false
      });
    }
  }
});