【vue+El-element】实现todolist

好像拖更了很久,很抱歉,最近想了一下css和js等内容还是不总结了,本来内容就多,不是一篇博客能说完的,而且我也只学了皮毛,以后还是通过实例的方式来分享一下学过的东西,希望能帮到大家。

目录

一、实现功能

​ 二、实现方法

1.数据的传递

2.按钮的实现

3.全选按钮的实现

4.记录用户键盘数据

三、源代码(感兴趣自己试试)

总结

前言

最初了解到这个todolist的时候我还感觉挺简单的,但实现确实遇到了好多问题(我太菜了),而且在网上看大佬的文章,看不懂(哭),所以我会将实现思路和学到了一些新方法分享出来,希望能帮助理解,然后源代码粘到文末,也欢迎大家跟我一起交流。

一、实现功能

1.有一个输入框,记录想完成的事件,用户enter直接输入

2.有一个正在做任务框,记录正在做的任务

3.有一个已完成框,可以一键删除所有已完成任务

正在做的事项:

        可以恢复到想完成,也可以进入删除框,

        支持每个事项的点选,也支持一键转移

具体实现样式:

 二、实现方法

1.数据的传递

        通过上文对于需求的描述,或者对于todolist的了解,应该能知道数据简单方便的传递是最核心的要求,最开始的时候我是想建三个数组分别存储,实际写的时候发现这样太复杂了,传递数据很困难,最后我决定给数据一个status变量,数据一直都在数组中,但是我可以进行有选择的展示,运用筛选的思想(vue中也有filter组件)

  computed: {
    isNew () {
      return this.list.filter(value => {
        if (value.status === 'new') {
          return value
        }
      })
    },
    isFinish () {
      return this.list.filter(value => {
        if (value.status === 'finish') {
          return value
        }
      })
    },
    isDelete () {
      return this.list.filter(value => {
        if (value.status === 'delete') {
          return value
        }
      })
    }
  },

利用了vue的计算属性,三个不同的变量分别代表创建框,正在做和已完成展示的属性

<el-checkbox v-for="item in isNew" :key="item.name" @change="turnFinish(item)" class="checkbox" style="margin-top:10px">{
   
   {item.name}}</el-checkbox>

页面搭建的时候使用v-for就可以了(我以前一直以为item in isNew只能是数组,其实方法也是可以的)

2.按钮的实现

        可以看到页面上除了展示内容的就是按钮了,实现思想就是绑定一个@click事件,然后改变数据的status就好了,这里重点讲一下删除按钮吧

        不是其方法的实现,而是我在测试的时候发现,如果点击的过快,数据的传递会发生问题,因为你点击了,但请求接口的操作还没有执行完,这时候需要设置一个延时装置使用户不能点击那么快,el同样提供了loading组件https://element.eleme.cn/#/zh-CN/component/loading,我这里的实现思路就是 setTimeout(this.clickStatus, 100),给一个延时时间使用户不能点击。

         HTML代码

<el-button type="text" style="width:30px; color:#E6A23C" @click="turnDelete(item)" :disabled="canClick">删除</el-button>

 在 :disabled属性上绑定一个变量,默认为false,当执行事件的时候变为true,这时候用户就不能点击,然后等计时结束再变成false,this.clickStatus实现的就是改变这个值。

turnDelete (item) {
      if (this.canClick === false) {
        this.canClick = true
        item.status = 'delete'
        console.log(this.list)
        setTimeout(this.clickStatus, 100)
      }
    },
clickStatus () {
      this.canClick = false
    },

3.全选按钮的实现

        需求中提到了一键转移要求,就是点击全选时候可将旗下所有数据状态改变,全选功能的实现el也给出了案例https://element.eleme.cn/#/zh-CN/component/checkbox

        但是我刚开始学的时候确实看不懂(哭), 后来请教了大佬后,它这个状态是由两个参数共同控制的,checkedindeterminate,具体说明如下: 一个控制样式一个控制是否点选

 

         感兴趣可以自行研究,我这里提供结果以便大家理解:

全选:checked = true  ,indeterminate = false

全不选:checked =  false,indeterminate = false

选了几个:checked = false,indeterminate = true

所以实现自己的按钮的时候要严格按照他提供的逻辑去写

// 全选按钮绑定checkAll事件
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange" style="width:60%; zoom:160%">click all</el-checkbox>

// 下面展示的check-group要绑定handleCheckedCitiesChange,这样才是双向实现
<el-checkbox-group v-model="alreadyChecked" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="item in isFinish" :key="item.name" :label="item.name" class="checkbox">
              {
   
   {item.name}}
              <el-button type="text" style="width:30px" @click="turnNew(item)" :disabled="canClick">恢复</el-button>
              <el-button type="text" style="width:30px; color:#E6A23C" @click="turnDelete(item)" :disabled="canClick">删除</el-button>
            </el-checkbox>

        具体实现逻辑仿照提供案例写,因为doing框的数据并不就是list的全部数据,而是status = ‘finish’这一类数据,所以判断前要先进行数据的筛选(我写的时候还犯过特别低级的错误,函数内部定义的变量,在调用的时候使用this. variable,然后出来就是undefine)

        遍历一个数组内部数据map和forEach都可以,我还没有比较过这两种方法的区别,下次研究一下

handleCheckAllChange (val) {
      this.alreadyChecked = val ? this.list.map(x => {
        if (x.status === 'finish') {
          return x.name
        }
      }) : []
      this.isIndeterminate = false
    },
    handleCheckedCitiesChange (value) {
      let checkedCount = value.length
      let finishCount = 0
      this.list.forEach(element => {
        if (element.status === 'finish') {
          finishCount = finishCount + 1
        }
      })
      this.checkAll = checkedCount === finishCount
      this.isIndeterminate = checkedCount > 0 && checkedCount < finishCount
    }

4.记录用户键盘数据

如何在用户使用enter的时候就记录下相关数据?

可以使用keyup属性,这是jQuery相关知识,我还没有学过,感兴趣自行了解。

@keyup.enter.native="enter"

三、源代码(感兴趣自己试试)

HTML

<template>
  <div>
    <el-row>
      <el-col :span="24">
        <div class="bg-purple-dark grid-content">
          <el-tooltip effect="dark" content="记录每日代办" placement="right">
            <p class="header">Todolist</p>
          </el-tooltip>
        </div>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="8">
        <div class="bg-purple grid-content">
          <el-tooltip effect="dark" content="记录想做的事情" placement="top">
            <h3 class="subtitle">Wating</h3>
          </el-tooltip>
          <el-input placeholder="please write down something" v-model="input" clearable @keyup.enter.native="enter"></el-input>
          <el-checkbox v-for="item in isNew" :key="item.name" @change="turnFinish(item)" class="checkbox" style="margin-top:10px">{
   
   {item.name}}</el-checkbox>
        </div>
      </el-col>
      <el-col :span="8">
        <div class="bg-purple-light grid-content">
          <el-tooltip effect="dark" content="正在做的事项" placement="top">
          <h3 class="subtitle">Doing</h3>  </el-tooltip>
          <div>
            <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange" style="width:60%; zoom:160%">click all</el-checkbox>
            <el-tooltip effect="light" content="一键恢复" placement="left">
              <el-button type="info" icon="el-icon-refresh-left" circle @click="allTurnNew"></el-button>
            </el-tooltip>
            <el-tooltip effect="light" content="一键删除" placement="right">
              <el-button type="warning" icon="el-icon-delete" circle @click="allTurnDelete"></el-button>
            </el-tooltip>
          </div>
          <el-checkbox-group v-model="alreadyChecked" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="item in isFinish" :key="item.name" :label="item.name" class="checkbox">
              {
   
   {item.name}}
              <el-button type="text" style="width:30px" @click="turnNew(item)" :disabled="canClick">恢复</el-button>
              <el-button type="text" style="width:30px; color:#E6A23C" @click="turnDelete(item)" :disabled="canClick">删除</el-button>
            </el-checkbox>
          </el-checkbox-group>
        </div>
      </el-col>
      <el-col :span="8">
        <div class="bg-purple grid-content">
          <el-tooltip effect="dark" content="已经完成的事项" placement="top">
          <h3 class="subtitle">Finish</h3>  </el-tooltip>
          <el-tooltip effect="light" content="清空内容" placement="right">
            <el-button type="danger" round @click="clean">清空回收站</el-button>
          </el-tooltip>
          <p v-for="item in isDelete" :key="item.name" class="delete">{
   
   {item.name}}</p>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

JS

<script>
export default {
  data () {
    return {
      input: '',
      list: [],
      // for clickAll checkbox
      checkAll: false,
      isIndeterminate: false,
      finishList: [],
      alreadyChecked: [],
      canClick: false
    }
  },
  computed: {
    isNew () {
      return this.list.filter(value => {
        if (value.status === 'new') {
          return value
        }
      })
    },
    isFinish () {
      return this.list.filter(value => {
        if (value.status === 'finish') {
          return value
        }
      })
    },
    isDelete () {
      return this.list.filter(value => {
        if (value.status === 'delete') {
          return value
        }
      })
    }
  },

  methods: {
    // record the things people input
    enter () {
      let isRepeat = false
      this.list.map(x => {
        if (x.name === this.input) {
          isRepeat = true
        }
      })
      if (this.input === '') {
        this.$message({
          message: 'please input something',
          type: 'warning'
        })
      } else if (isRepeat === true) {
        this.$message('this list is repeat, please write another')
      } else {
        this.list.push({
          name: this.input,
          status: 'new'
        })
      }
      this.input = ''
      console.log(this.list)
    },
    turnFinish (item) {
      item.status = 'finish'
    },
    turnNew (item) {
      if (this.canClick === false) {
        this.canClick = true
        item.status = 'new'
        setTimeout(this.clickStatus, 100)
      }
    },
    turnDelete (item) {
      if (this.canClick === false) {
        this.canClick = true
        item.status = 'delete'
        console.log(this.list)
        setTimeout(this.clickStatus, 100)
      }
    },
    clean () {
      this.list.forEach(element => {
        if (element.status === 'delete') {
          element.status = 'done'
        }
      })
    },
    clickStatus () {
      this.canClick = false
    },
    allTurnNew () {
      if (this.checkAll === true && this.isIndeterminate === false) {
        this.list.forEach(element => {
          if (element.status === 'finish') {
            element.status = 'new'
          }
        })
        this.checkAll = false
        // 取消对于所有事项的勾选
        this.alreadyChecked = []
      }
    },
    allTurnDelete () {
      if (this.checkAll === true && this.isIndeterminate === false) {
        this.list.forEach(element => {
          if (element.status === 'finish') {
            element.status = 'delete'
          }
        })
        this.checkAll = false
      }
    },
    handleCheckAllChange (val) {
      this.alreadyChecked = val ? this.list.map(x => {
        if (x.status === 'finish') {
          return x.name
        }
      }) : []
      this.isIndeterminate = false
    },
    handleCheckedCitiesChange (value) {
      let checkedCount = value.length
      let finishCount = 0
      this.list.forEach(element => {
        if (element.status === 'finish') {
          finishCount = finishCount + 1
        }
      })
      this.checkAll = checkedCount === finishCount
      this.isIndeterminate = checkedCount > 0 && checkedCount < finishCount
    }
  }
}
</script>

总结

如果觉得对你有帮助,请点一个赞吧,你的支持是作者最大的动力!

猜你喜欢

转载自blog.csdn.net/qq_41443611/article/details/119907552