和我一起入坑-Vue入门-ToDoList

鱼在我这里

和我一起入坑-Vue入门-ToDoList

本项目是仿照这个做滴 ToDoList 。使用Vue实现这个代办事项功能。完整的项目在这里GitHub vue-todolist

(一)基本功

Vue官方文档 了解一下

  1. 前置项
    安装Node,建议使用nvm安装,逼格比较高(手动滑稽)
  2. 然后全局安装 Vue CLI
    居然还改名了

    npm install -g @vue/cli
  3. 创建项目

    vue create vue-todolist
  4. 启动CLI服务

    cd vue-todolist
    $ npm run serve
  5. 目录结构
    根据自己的习惯创建文件,并删除多余的代码。我是如下创建的:

    ├── 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 &copy; 2014 todolist.cn
      <a>clear</a>
    </footer>
  </div>
</template>

复制完成后,页面长这样
html和css

(三)实现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 &copy; 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?
因为复杂的我不会!

说实话,你到底想干嘛?
本来我是想对三个框架进行对比,结果发现技术不佳,学艺不深,无法对其进行比对。所以结论是喜欢哪个就用哪个好了 (这样不好,不要学我)

自问自答是不是很尴尬?
是的。

阅读 14.1k

春风十里,有鱼陪你。

41 声望
3 粉丝
0 条评论

春风十里,有鱼陪你。

41 声望
3 粉丝
文章目录
宣传栏