JSFiddle - React, Tailwind, and code Playground
by marketingaddict8
HTML
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/index.css">
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<input class="new-todo" autofocus autocomplete="off" placeholder="What needs to be done?" v-model="newTodo" @keyup.enter="addTodo">
</header>
<section class="main" v-show="todos.length">
<ul class="todo-list">
<li v-for="todo in todosList" class="todo" :key="todo.id" :class="{ editing: todo == editedTodo }">
<div class="view">
<label @click="editTodo(todo)">{{ todo.title }}</label>
<button class="destroy" @click="removeTodo(todo)"></button>
</div>
<input class="edit" type="text" v-model="todo.title" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">
</li>
</ul>
</section>
</section>
CSS
[v-cloak] {
display: none;
}
.todo-list {
overflow: auto;
}
JavaScript
// Full spec-compliant TodoMVC with localStorage persistence
// and hash-based routing in ~120 effective lines of JavaScript.
// localStorage persistence
var STORAGE_KEY = 'todos-vuejs-2.0'
var todoStorage = {
fetch: function() {
var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
todos.forEach(function(todo, index) {
todo.id = index
})
todoStorage.uid = todos.length
return todos
},
save: function(todos) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
}
}
// app Vue instance
var app = new Vue({
// app initial state
data: {
todos: todoStorage.fetch(),
newTodo: '',
editedTodo: null,
/* visibility: 'all' */
},
// watch todos change for localStorage persistence
watch: {
todos: {
handler: function(todos) {
todoStorage.save(todos)
},
deep: true
}
},
// computed properties
// http://vuejs.org/guide/computed.html
computed: {
todosList: function() {
return this.todos;
},
},
// methods that implement data logic.
// note there's no DOM manipulation here at all.
methods: {
addTodo: function() {
var value = this.newTodo && this.newTodo.trim()
if (!value) {
return
}
this.todos.push({
id: todoStorage.uid++,
title: value,
/* completed: false */
})
this.newTodo = ''
},
removeTodo: function(todo) {
this.todos.splice(this.todos.indexOf(todo), 1)
},
editTodo: function(todo) {
this.beforeEditCache = todo.title
this.editedTodo = todo
},
doneEdit: function(todo) {
if (!this.editedTodo) {
return
}
this.editedTodo = null
todo.title = todo.title.trim()
if (!todo.title) {
this.removeTodo(todo)
}
},
cancelEdit: function(todo) {
this.editedTodo = null
todo.title = this.beforeEditCache
},
},
// a custom directive to wait for the DOM to be...