和我一起入坑-Vue入门-ToDoList
本项目是仿照这个做滴 ToDoList 。使用Vue实现这个代办事项功能。完整的项目在这里GitHub vue-todolist。
(一)基本功
Vue官方文档 了解一下
- 前置项
安装Node,建议使用nvm安装,逼格比较高(手动滑稽) -
然后全局安装 Vue CLI
居然还改名了npm install -g @vue/cli
-
创建项目
vue create vue-todolist
-
启动CLI服务
cd vue-todolist $ npm run serve
-
目录结构
根据自己的习惯创建文件,并删除多余的代码。我是如下创建的:├── public ├── src │ ├── assets │ │ └── css │ │ └── styles.css │ ├── utils │ │ └── utils.js │ ├── views │ │ └── Home.vue │ ├── App.vue │ ├── main.js │ ├── router.js
(二)Html和CSS部分
打开控制台将样式文件复制粘贴到styles.css文件中。在main.js中导入样式
// main.js
import '@/assets/css/styles.css'
将html复制粘贴到Home.vue中的template中
<!-- Home.vue -->
<template>
<div>
<header>
<section>
<label for="title">ToDoList</label>
<input type="text" placeholder="添加ToDo"/>
</section>
</header>
<section>
<h2>正在进行
<span>1</span>
</h2>
<ol class="demo-box">
<li>
<input type="checkbox">
<p>记得吃药</p>
<a>-</a>
</li>
</ol>
<h2>已经完成
<span>1</span>
</h2>
<ul>
<li draggable="true">
<input type="checkbox"checked="checked">
<p>记得吃饭</p>
<a>-</a>
</li>
</ul>
</section>
<footer>
Copyright © 2014 todolist.cn
<a>clear</a>
</footer>
</div>
</template>
复制完成后,页面长这样
(三)实现ToDoList的功能
添加代办事项
使用v-model 指令在input框上创建双向数据绑定。并为按键添加修饰符,监听键盘enter键。
<input type="text" v-model="todo" @keyup.enter="addTodo" placeholder="添加ToDo" />
data () {
return {
todo: '',
todoList: [],
todoLen: 0
}
},
methods: (
addTodo () {
let todoObj = {
todo: this.todo,
done: false
}
this.todoList.push(todoObj)
this.todoLen++
this.todo = ''
},
)
循环添加的事项
使用v-for将所添加的事项循环显示,并使用v-if条件渲染只显示的内容。
<li v-for="(item, index) in todoList" :key="index" v-if="item.done === false">
<input type="checkbox">
<p>{{item.todo}}</p>
<a>-</a>
</li>
这个时候就可以看到添加的内容了
切换状态及删除功能
绑定切换状态、删除的事件
<h2>正在进行
<span>{{todoLen}}</span>
</h2>
<ol class="demo-box">
<li v-for="(item, index) in todoList" :key="index" v-if="item.done === false">
<input type="checkbox" @change="changeTodo(index,true)">
<p>{{item.todo}}</p>
<a @click="deleteTodo(index,true)">-</a>
</li>
</ol>
<h2>已经完成
<span>{{todoList.length - todoLen}}</span>
</h2>
<ul>
<li v-for="(item, index) in todoList" :key="index" v-if="item.done === true">
<input type="checkbox" @change="changeTodo(index,false)" checked='checked'>
<p>{{item.todo}}</p>
<a @click="deleteTodo(index,false)">-</a>
</li>
</ul>
根据done的值来控制是否显示,在点击事件中对done取反。对未完成的事项长度进行加减。
changeTodo (index, done) {
if (done) {
this.todoLen--
this.todoList[index].done = true
} else {
this.todoLen++
this.todoList[index].done = false
}
},
deleteTodo (index, done) {
if(done){
this.todoLen--
}
this.todoList.splice(index, 1)
},
到此为止,这个功能就算完成了,但是当我们刷新页面后数据就不见了,这里我们需要用到localStorage。
localStorage的使用
todoList数组的每一次增加和删减都会用到localStorage,将localStorage封装起来方便使用。
// utils.js
export function setItem (key, value) {
localStorage.setItem(key, JSON.stringify(value))
}
export function getItem (key) {
return JSON.parse(localStorage.getItem(key))
}
export function removeItem (key) {
localStorage.removeItem(key)
}
导入utils
import * as Utils from '@/utils/utils'
在数组的每一次改变都需要使用Utils.setItem进行数据的存储。在addTodo方法中,一定要对Utils.getItem返回的数据进行判断,否则会报“Cannot read property 'push' of null”
addTodo () {
let todoObj = {
todo: this.todo,
done: false
}
var tempList = Utils.getItem('todoList')
if (tempList) {
tempList.push(todoObj)
Utils.setItem('todoList', tempList)
} else {
var tempData = []
tempData.push(todoObj)
Utils.setItem('todoList', tempData)
}
this.todoList.push(todoObj)
this.todoLen++
this.todo = ''
},
deleteTodo (index, done) {
if(done){
this.todoLen--
}
this.todoList.splice(index, 1)
Utils.setItem('todoList', this.todoList)
},
changeTodo (index, done) {
if (done) {
this.todoLen--
this.todoList[index].done = true
Utils.setItem('todoList', this.todoList)
} else {
this.todoLen++
this.todoList[index].done = false
Utils.setItem('todoList', this.todoList)
}
},
初始事件
在初始的时候对未完成事项进行自加运输,以得到初始的长度。
methods: {
initTodo () {
var todoArr = Utils.getItem('todoList')
if (todoArr) {
for (let i = 0, len = todoArr.length; i < len; i++) {
if (todoArr[i].done === false) {
this.todoLen++
}
}
this.todoList = todoArr
}
},
}
mounted () {
this.initTodo()
}
还有页脚的clear按钮
<footer>Copyright © 2014 todolist.cn<a @click="clearData()">clear</a></footer>
clearData () {
localStorage.clear()
this.todoList = []
this.todoLen = 0
}
说在后面的话
完整的项目在这里GitHub vue-todolist。
实际上,关于这个ToDoList我写了三个小demo,分别是
Angular ToDoList的小博文,完整的项目在这里GitHub ng-first。
React Native ToDoList的小博文,完整的项目在这里GitHub AwesomeProject。
Vue ToDoList的小博文,完整的项目在这里GitHub vue-todolist。
为什么写了三个呢?
因为我闲啊!!
为什么都是写这种超级简单的小demo?
因为复杂的我不会!
说实话,你到底想干嘛?
本来我是想对三个框架进行对比,结果发现技术不佳,学艺不深,无法对其进行比对。所以结论是喜欢哪个就用哪个好了 (这样不好,不要学我) 。
自问自答是不是很尴尬?
是的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。