用vue做todolist

<template>
<div class="hello">
<div style="height:25px;line-height:25px;color:#a26777">This is Todos</div>
<input type="text" style="width: 100%;height: 30px;border: 1px solid #a26777;padding: 0 3px;
box-sizing: border-box;" v-model="getActivity" placeholder="宝贝,请输入你的日常计划~" @keyup.enter="onEnter">
<ul>
<li style="width:100%;background-color:#87d1d0;height:25px;margin:0;border:1px solid white;line-height:25px" :class="{becomeRed:item.isfinished}" @click="todos(item)" v-for="(item,index) in todoList" :key="index">{{item.eat}}
<span style="float: right;" @click="deleteMe(index)">delete!</span>
</li>
</ul>
<div @click="checkAll()" style="width: 30%;margin: 0 auto;background-color: #a26777;height: 25px;line-height: 25px;border-radius:4px;color:white" :class="{checkedColor:checkedOrNot}">Check all</div>
<div style="margin-top: 10px; width: 50%;margin: 10px auto; background-color: #a26777;height: 25px;line-height: 25px;
border-radius:4px;color:white" v-if="getTheChange" >{{numleft}}</div>
<div style="margin-top: 10px; width: 50%;margin: 10px auto; background-color: #a26777;height: 25px;line-height: 25px;
border-radius:4px;color:white" v-if="!getTheChange" @click="deleteAll()" >Delete completed</div>
<div style="border-bottom:1px dashed #a26777"></div>
<div style="width:50px;height:50px;border-radius:25px;line-height:50px;color:white;text-align:center;background-color:#a26777;font-size:12px;margin:10px auto;background:linear-gradient(to right, #87D1D0 , #a26777);" @click="toRecord">
Records
</div>
</div>
</template>
<script>
import Store from './store.js'
import router from '../router/index.js'
export default {
data () {
return {
getActivity:'',
todoList:Store.fetch()||[],
checked:false,
checked2:false,
numleft:Store.fetch().length+'times left',//这个是获取缓存里面有多少项没有完成
newIndex:0,
getTheChange:true,
checkedList:[],
checkedOrNot:false,
count:0,
allList:Store.fetchAll()||[],//注意了,Store.fetchAll()如果不写的话,让你从第一个页面进入第二个,再进入第一个页面输入enter时,会重新计算
getTime:''
}
},
methods:{
//这个表示我想选中这个项来删除,实在是不想做圆圈的样式,宝宝们懂就好~
todos:function (item){
item.isfinished=!item.isfinished
},
//你enter的时候,就会多一项,你要完成的东东
onEnter:function () {
this.todoList.push ({ //这里的存储是为了时时更新所有显示的list的状态
eat:this.getActivity,
isfinished:false
})
this.allList.push({ //为了第二个页面去获取你所有写过的list
eat:this.getActivity,
isfinished:false,
time:this.getTime
})
this.getActivity='' //这里置空主要是为了好输入啦
},
deleteMe:function (index){ //删除某一项
this.todoList.splice(index,1)
},
checkAll:function(){ //全选,全选可以表示已完成,欲删除的状态
this.checkedOrNot=!this.checkedOrNot
var _this=this
if(_this.checkedOrNot){
_this.todoList.forEach(element => {
element.isfinished=true
});
}else{
_this.todoList.forEach(element => {
element.isfinished=false
});
}
},
deleteAll:function (){//删除所有的,就是将整个数据做一个删选,文字变白就表示欲删除,将不需要删除的 (isfinished==false)留下来
this.checked=true
this.todoList= this.todoList.filter((element)=>{
return element.isfinished==false;
})
},
getSomeInit:function(){//只有有欲删除的,会显示deleted completed,没有就显示num+times left
this.checkedList=this.todoList.filter((element)=>{
return element.isfinished==false;
})
if(this.checkedList<this.todoList){
this.getTheChange=false;
}else{
this.getTheChange=true;
}
},
toRecord:function (){
router.push({ path: `/loginDetail` })
},
getNow:function(){ //这里是当前时间的转化,存到内存里面去,在第二个页面显示
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
if (month < 10) {
month = "0" + month;
}
if (day < 10) {
day = "0" + day;
}
this.getTime= year + "-" + month + "-" + day;
}
},
watch:{
todoList:{
handler:function (item) {
Store.setSome(item)
this.index=item.length
this.numleft=this.index+'times left'
this.checkedList=this.todoList.filter((element)=>{
return element.isfinished==false;
})
if(this.checkedList<this.todoList){
this.getTheChange=false;
}else{
this.getTheChange=true;
}
},
deep:true //必须要加
},
allList:{
handler:function (item) {
Store.setAllSome(item)
},
deep:true
}
},
created:function () {
this.getSomeInit()
this.getNow()
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.becomeRed{
color:white;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
@import "../assets/var.less";
@loading-bar-color: @color-white;
.checkedColor{
color:white;
}
#loadingbar {
position: fixed;
z-index: 2147483647;
top: 100px;
left: -6px;
width: 1%;
height: 2px;
background: @loading-bar-color;
-moz-border-radius: 1px;
-webkit-border-radius: 1px;
border-radius: 1px;
-moz-transition: all 500ms ease-in-out;
-ms-transition: all 500ms ease-in-out;
-o-transition: all 500ms ease-in-out;
-webkit-transition: all 500ms ease-in-out;
transition: all 500ms ease-in-out;
}
.checkedColor,.checked2{
color:white;
}
#loadingbar.left {
left: 100%;
right: 0px;
width: 100%;
}
#loadingbar.up {
left: 0px;
top: 100%;
width: 5px;
bottom: 0px;
height: 100%;
}
#loadingbar.down {
left: 0;
width: 5px;
height: 0;
}
#loadingbar.waiting dd, #loadingbar.waiting dt {
-moz-animation: pulse 2s ease-out 0s infinite;
-ms-animation: pulse 2s ease-out 0s infinite;
-o-animation: pulse 2s ease-out 0s infinite;
-webkit-animation: pulse 2s ease-out 0s infinite;
animation: pulse 2s ease-out 0s infinite;
}
#loadingbar dt {
opacity: .6;
width: 180px;
right: -80px;
clip: rect(-6px,90px,14px,-6px);
}
#loadingbar dd {
opacity: .6;
width: 20px;
right: 0;
clip: rect(-6px,22px,14px,10px);
}
#loadingbar dd, #loadingbar dt {
position: absolute;
top: 0;
height: 2px;
-moz-box-shadow: rgb(255, 156, 50) 1px 0 6px 1px;
-ms-box-shadow: rgb(255, 156, 50) 1px 0 6px 1px;
-webkit-box-shadow: rgb(255, 156, 50) 1px 0 6px 1px;
box-shadow: rgb(255, 156, 50) 1px 0 6px 1px;
-moz-border-radius: 100%;
-webkit-border-radius: 100%;
border-radius: 100%;
}
#loadingbar.left dt {
opacity: .6;
width: 180px;
left: -4px;
clip: rect(-6px,185px,14px,25px);
}
#loadingbar.left dd {
opacity: .6;
width: 20px;
left: 0;
margin: 0;
clip: rect(-6px,22px,14px,0px);
}
#loadingbar.left dd, #loadingbar.left dt {
top: 0;
height: 2px;
}
#loadingbar.down dt {
opacity: .6;
height: 180px;
top: auto;
bottom: -47px;
clip: rect(-6px,20px,130px,-6px);
}
#loadingbar.down dd {
opacity: .6;
height: 20px;
top: auto;
bottom: 0;
clip: rect(-6px,22px,20px,10px);
margin: 0;
}
#loadingbar.down dd, #loadingbar.down dt {
left: -5px;
right: auto;
width: 10px;
}
#loadingbar.up dt {
opacity: .6;
height: 180px;
bottom: auto;
top: -10px;
clip: rect(13px,20px,190px,-6px);
}
#loadingbar.up dd {
opacity: .6;
height: 20px;
bottom: auto;
top: 0;
clip: rect(-6px,22px,25px,10px);
margin: 0;
}
#loadingbar.up dd, #loadingbar.up dt {
left: -5px;
right: auto;
width: 10px;
}
@keyframes pulse {
30% { opacity:0.6; }
60% { opacity:0; }
100% { opacity:0.6; }
}
@-moz-keyframes pulse
{
30% { opacity:0.6; }
60% { opacity:0; }
100% { opacity:0.6; }
}
@-ms-keyframes pulse
{
30% { opacity:0.6; }
60% { opacity:0; }
100% { opacity:0.6; }
}
@-webkit-keyframes pulse
{
30% { opacity:0.6; }
60% { opacity:0; }
100% { opacity:0.6; }
}
.loadingbar-wrapper {
position: absolute;
top: 0;
left: 0;
z-index: 1000;
width: 100%;
}
.loadingbar-wrapper::after {
position: absolute;
right: 5px;
top: 10px;
z-index: 1001;
content: '';
width: 16px;
height: 16px;
border-radius: 100%;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
border: 2px solid @loading-bar-color;
border-bottom-color: transparent;
-webkit-animation: rotate 0.75s 0s linear infinite;
animation: rotate 0.75s 0s linear infinite;
}
@keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg) }
}
</style>
store.js
const store_Key='todolist'
const store_all_key='allTodolist'
export default{
fetch (){
return JSON.parse(window.localStorage.getItem(store_Key)||'[]')
},
fetchAll() {
return JSON.parse(window.localStorage.getItem(store_all_key) || '[]')
},
setSome(item){
window.localStorage.setItem(store_Key, JSON.stringify(item))
},
setAllSome(item){
window.localStorage.setItem(store_all_key, JSON.stringify(item))
}
}
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import loginDetail from '@/components/loginDetail'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/loginDetail',
name: 'loginDetail',
component: loginDetail
}
]
})
这个功能有点仿小程序高校todos,后面的储存记录在状态上没有做处理~
实现了什么?
1.全部删除
2.单个删除
3.欲删除的状态的下面文字的变化
4.怎么把所有的数据存储起来
具体的都写在了那个里面
要是不足之处,欢迎指正~
多运动,记得提前养发,劳逸结合-_-
用vue做todolist的更多相关文章
- vue 做一个简单的TodoList
目录结构 index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...
- 用vue做app内嵌页遇到的坑
公司要求用vue做一个微信端的网站,其中还包含一些app的内嵌页.开始的时候没想那么多,就直接用vue-cli搭了一个单页的vue项目,可随着项目越做越大,页面越来越多,问题就开始暴露出来了. 众所周 ...
- vue做的第二个app
用vue做应用最好的还是组件的复用上次做饿了吗的app封装了一个评分star的组件只要引入组件传入size大小和score分数就行了,这次做豆瓣直接就就用上了不用重复写代码.不过vue做单页应用全部挂 ...
- 使用vue做项目
使用vue做项目需要用到node.js的npm来管理包 所以我们需要先下载node.js然后通过node的npm来管理包 安装完 nodejs后 我们需要执行 npm install vue-cli ...
- vue demo todo-list
html <input type='text' v-model="todoItem" v-on:keyup.enter='addItem'> <ul> &l ...
- Vue 做项目经验
Vue 做项目经验 首先需要知道最基本的东西是: Vue 项目打包:npm run build Vue生成在网页上看的端口:npm run dev 修改端口号的地方在: config文件夹下index ...
- Vue源码分析(一) : new Vue() 做了什么
Vue源码分析(一) : new Vue() 做了什么 author: @TiffanysBear 在了解new Vue做了什么之前,我们先对Vue源码做一些基础的了解,如果你已经对基础的源码目录设计 ...
- 使用vue做项目如何提高代码效率
最近做了两个vue项目,算上之前做的两个项目,总共有四个vue项目的经验了,但是总体来说写的代码质量不是很高,体现在以下几点 1.代码没有高效的复用 自从使用vue做项目之后,以前使用面向过程变成的习 ...
- vue 实现todolist,包含添加,删除,统计,清空,隐藏功能
vue 实现todolist,包含添加,删除,统计,清空,隐藏功能 添加:生成列表结构(v-for+数组).获取用户输入(v-model).通过回车新增数据(v-on+.enter) 删除:点击删除指 ...
随机推荐
- 【转载】C#中string类使用Replace方法来替换字符串
在C#的字符串操作过程中,有时候需要替换字符串中的某个子字符串,此时就可以使用到字符串类自带的Replace方法来实现,Replace方法将查找到所有符合被替换的子字符串,然后将之全部替换为目标字符串 ...
- js --桥接模式
定义: 将抽象部分与它的实现部分分离,使他们都可以独立的变化. 也就是说,桥接模式里面有两个角色: - 扩充抽象类 - 具体实现类 在写桥接模式之前,想在写一下关于抽象的理解.我觉得抽象这个概念过于抽 ...
- HBuilderX打包成安卓或苹果app之后的调试问题,避免每次都要打包
一.使用VScode安装 Live Server插件 二.使用:安装成功后---->>新建一个index.html 写入内容如下图所示 注:href地址是你在电脑上启动该项目的访问地址(此 ...
- Node.js学习(第二章:node核心模块--fs)
前言 Node.js中赋予了JavaScript很多在浏览器中没有的能力,譬如:文件读写,创建http服务器等等,今天我们就来看看在node中怎样用JavaScript进行文件的读写操作. 读文件 我 ...
- go语言实现限流器
本文:https://chai2010.cn/advanced-go-programming-book/ch5-web/ch5-06-ratelimit.html Ratelimit 服务流量限制 计 ...
- AOP初识
AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理.缓存.对象池管理以及日志记录.AOP将这些分散在各 ...
- 跨服务器查询sql语句样例(转)
若2个数据库在同一台机器上: insert into DataBase_A..Table1(col1,col2,col3----) select col11,col22,col33-- from Da ...
- requests-html模块(下)
render方法 我们先理一下关系requests和的作者是同一个人,pyppeteer是nodejs中puppeteer的非官方实现 requests-html调用的pyppeteer与浏览器进行交 ...
- JavaSE字符串日期与时间拼接小列子与JSON小列子
1.在对象中有个字段为Timestamp类型,需要将数据库的开始日期字段和开始时间字段拼接成一个字段开始字段 private static Timestamp getDateTime(String d ...
- 【独家】K8S漏洞报告 | 近期bug fix解读
安全漏洞CVE-2019-3874分析 Kubernetes近期重要bug fix分析 Kubernetes v1.13.5 bug fix数据分析 ——本周更新内容 安全漏洞CVE-2019-387 ...