你好吗
````
<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" v-cloak>
<input id="toggle-all" class="toggle-all" type="checkbox" v-model="allDone">
<label for="toggle-all"></label>
<ul class="todo-list">
<li v-for="todo in filteredTodos"
class="todo"
:key="todo.id"
:class="{ completed: todo.completed, editing: todo == editedTodo }">
<div class="view">
<input class="toggle" type="checkbox" v-model="todo.completed">
<label @dblclick="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>
<footer class="footer" v-show="todos.length" v-cloak>
<span class="todo-count">
<strong>{{ remaining }}</strong> {{ remaining | pluralize }} left
</span>
<ul class="filters">
<li><a href="#/all" :class="{ selected: visibility == 'all' }">All</a></li>
<li><a href="#/active" :class="{ selected: visibility == 'active' }">Active</a></li>
<li><a href="#/completed" :class="{ selected: visibility == 'completed' }">Completed</a></li>
</ul>
<button class="clear-completed" @click="removeCompleted" v-show="todos.length > remaining">
Clear completed
</button>
</footer>
</section>
````
````
//保存成一个变量,好处 如果有变动,改动vlaue值就行
var STORAGE_KEY = 'todos'
var todoStorage = {
fetch: funciton (){
//获取本地存储
var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
todos.forEach(function (todo, index){ //获取每个todo信息
todo.id = index
//todo对应的index --id 0 1 2 3
//:key="todo.id"
})
todoStorage.uid = todos.length
return todos
},
//保存变动后todos保存到 localStorage,需要转化成string
save: function (todos){
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
}
}
//过滤器
var filters= {
//返回全部列表
all: function (todos){
return todos
},
//返回还没有完成的
active: function(todos){
return todos.filter(function (todo){
//返回一个新数组,是一个满足没有选中的列表项
return !todo.completed
})
},
//返回已经完成的
completed: function (todos){
return todos.filter(function(todo){
return todo.completed
})
}
}
var app = new Vue({
data: {
//页面需要的数据
todos: todoStorage.fetch(),
//
newTodo: '',
//当前必须存在一个状态
visibility: 'all',
editedTodos: null
},
//监听data属性
//监听到todos整体有变化,不就知道是不是有变化, 将改变后的todos本地存储
watch: {
todos:{
//监听todos变化, 回调函数接受两参数,新值和旧值
handler: function(todos){
todoStorage.save(todos)
},
deep: true
}
},
computed: {
filteredTodos: function() {
return filters[this.visibility](this.todos)
},
remianing: function() {
return filters.active(this.todos).length
},
allDone: function() {
get: function() {
return this.remiaing === 0
},
set: function() {
this.todos.forEach(function(todo){
//??????? value ---v-model 为啥在data中没有 comple又那体现的
todo.completed = value
})
}
}
},
//过滤 item的值
filters: {
pluralize: function(n) {
return n=== 1 ? 'item': 'items'
}
},
methods: {
//用户输入内容后回车 操作
addTodo : function(){
var value = this.newTodo && this.newTodo.trim()
//特殊情况: 没有输入内容 return
if(!value){
return
}
//有内容 ,加入到todos 中
this.todos.push({
id: todoStorage.uid++,
title: value,
completed: false
})
//将 变量清空, 下一次使用
this.newTodo = ''
},
//点击 x,删除li 也就是数组中找出一个指定元素 删除
removeTodo: function(todo) {
// splice(2,1) 删除替换数组中的第2 个元素的
//indexOf() 返回一个数组中给定元素的对应索引
this.todos.splice(this.todos.splice(todo),1)
},
editTodo: function(todo) {
},
doneTodo: function(todo) {
if(!this.editedTodo){
return
}
this.editedTodo = null
},
//点击键盘上的esc时 取消编辑
cancelEdit: function() {
},
//未选中时
removeCompleted: function() {
}
//双击输入框 编辑
editTodo: function (todo) {
this.beforeEditCache = todo.title
this.editedTodo = todo
},
// ???? 输入后,失去焦点(点击别处)或者 键盘点击enter时 完成
doneEdit: function (todo) {
if (!this.editedTodo) {
return
}
this.editedTodo = null
todo.title = todo.title.trim()
if (!todo.title) {
this.removeTodo(todo)
}
},
//点击键盘上的esc时 取消编辑
cancelEdit: function (todo) {
this.editedTodo = null
todo.title = this.beforeEditCache
},
//未勾选时
removeCompleted: function () {
this.todos = filters.active(this.todos)
}
}
})
//路由切换
function onHashChange() {
//当页面路由发生改变,要找到当前页面url中的hash
// hash === all actived completed
var visibility = window.location.hash.replace(/#\/?/, '')
//hash 存在,是all actived completed 之间任意个, 改变vue实例中的data-visibility
if(filters[visibility]){
app.visibility = visibility
}else {
//如果当前hash 是不存在的,那么默认为 all
window.location.hash = ''
app.visibility = 'all'
}
}
// 自定义指令
// 如果绑定指令元素上的value 存在, 为焦点状态
directives: {
'todo-focus': function (el, binding) {
if (binding.value) {
el.focus()
}
}
}
})
//监听hashchange事件, 执行函数onHashChange
window.addEventListener('hashchange', onHashChange)
onHashChange()
app.$mount('.todoapp')
````
````
[v-cloak] { display: none;}
````
网友评论