文章目录
采坑
- 在外部JS文件中使用vue的时候,传入的参数 【Vue】v没有大写,导致页面无法检测到Vue的使用,vue的语法不生效
- 使用 【git clone】命令时报错,将github地址的http前缀改为git
部分功能实现思路
新增项目
- 输入内容后按回车加入列表----->通过keyup.enter来处理新增
- 通过事件处理自带的参数event获取input的值,赋值给content
- id取列表数组length+1
- completed状态为false
- 将content、id、completed整合成对象,push到数组列表items
删除项目
删除单个项目
- 点击事件click处理
- 通过event获取index,splice删除
删除全部已完成项目
- 通过对列表数组调用filter,返回所有completed状态为false的项目即可
- html中还要对该按钮的显示隐藏进行判断 items.length>left (left下面实现)
// 删除所有完成项
handleClearCompleted() {
this.items = this.items.filter(item => {
return !item.completed
})
},
对已存在项目进行编辑
双击进入编辑状态
- 通过dblclick事件处理双击
- 编辑状态由TodoMVC自带的样式class='editing’来实现,即我只需要实现class的切换即可
- 通过定义变量currentItem,判断currentItem与该项目item是否相等来决定class
- 在dbclick事件处理中对currentItem赋值当前item
esc取消编辑
- 通过keyup.esc来处理
- 同上,只需要将editing的样式去掉就取消了编辑模式
- 在事件处理中将currentItem设为null,即可让上面判断不成立
通过回车或取消焦点来保存编辑
- 回车
- 通过keyup.enter来监听事件
- 取消焦点
- 通过blur来监听事件
- 处理
两个事件可以共用同一个处理函数
- 通过event获取输入的值value,并传入对应的item
- 若输入的内容为【空】或【纯空格】,则删除此项目
- 否则,通过给item.content赋值value来更新项目内容
// 回车或取消焦点时更新item内容
finishEdit(item, e) {
const content = e.target.value;
// 若输入框内容为空或纯空格,删除此项目
if (!content.trim()) {
this.items.splice(item.id - 1, 1);
return;
}
// 否则,更新项目内容
item.content = content;
// 取消编辑状态
this.currentItem = null;
},
自动获取焦点
- 通过【自定义指令】实现
// 注册全局指令,用于获取焦点(当然注册局部的也一样可以)
Vue.directive('get-focus', {
// bind(el, binding, vnode) {},
inserted(el, binding, vnode) {
// 获取焦点
el.focus()
},
update(el, binding, vnode, oldVnode) {
if (binding.value) {
el.focus();
}
},
// componentUpdated(el, binding, vnode) {},
// unbind(el, binding, vnode) {},
});
footer功能实现
剩余未完成项目数
- 通过computed计算属性left来更新值
- 通过对items使用filter来过滤所有completed状态为false的item,获取其length
- 对于显示的单词‘item’的单复数形式切换可以通过判断length是否为1实现
切换全选状态
- 通过computed计算属性toggleAll来设置getter和setter
- 在html中v-model双向绑定toggleAll
- getter
- toggleAll值为true时全选。即判断left是否为0,为0则返回true
- setter
- items遍历,给每一个item的completed状态设为true,实现全选
// 切换全选状态
toggleAll: {
get() {
// 判断当前是否全选,全选返回true,否则返回false
return this.left == 0
},
set(status) {
// 点击全选按钮后给所有item附加一致的状态
this.items.forEach(item => {
item.completed = status
})
}
}
根据路由切换显示的项目
- 通过window.onhashchange事件监听来处理路由切换
- 通过window.location.hash获取哈希值,并截取需要的部分
- 在vue中新增变量hashStatus,默认为all即显示所有项目
- hashStatus接收第2步截取的哈希值,作为新状态
- 在computed中新增计算属性hashItems来处理hashStatus的变化,变化成什么值,就用filter获取对应的内容,返回给html
- html的for循环改为 “items in hashItems”
- 为保证刷新后正确显示路由对应结果,要在js文件最后调用一次上面实现的onhashchange方法,更新路由状态
数据持久化
- 实现一个对象封装localStorage的get和set方法
- 实现一个深度监听watch来监听items的变化,当items改变就更新到localStorage中。
// 对localStorage进行操作
const itemStorage = {
getter() {
return JSON.parse(localStorage.getItem('todo-store') || '[]')
},
// 将数据保存在localStorage中
setter(val) {
localStorage.setItem('todo-store', JSON.stringify(val))
}
}
//....
// 通过watch监听items的变化,即时更新到storage中
watch: {
items: {
deep: true,
handler() {
itemStorage.setter(this.items)
}
}
},
TodoMVC App Template
Template used for creating TodoMVC apps
Getting started
-
Read the Application Specification before touching the template.
-
Delete this file and rename
app-readme.md
toreadme.md
and fill it out. -
Clone this repo and install the dependencies with npm by running:
npm install
.
License
This work by TasteJS is licensed under a Creative Commons Attribution 4.0 International License.