vue--Todolist(小项目)

todolist

  1. ui库
    sui
  2. 使用:
    引入第三方库: cdn
  3. 业务:
    1. 开关的切换
    2. 点击编辑, 出现一个弹框, 当我们键盘回车的是将, 将input框中的内容展示在页面上
    3. 当任务已完成时, 点击 删除 按钮 直接删除 , 当任务未完成时, 应该先出用户友好提示, 如果点击了确定, 在删除, 如果不点确定, 不能删除
    4. 底部按钮拥有不同的类名
    5. 底部按钮点谁 , 谁激活 — 》 加一个button-fill类名
      • 先随便起个名字, 然后判断这个名字和数据中名字是否对应, 如果对应就激活, 如果不对应就不激活
    6. 将数据进行分类
      分析: 列表渲染的数据 todos必须改变
      1. 有逻辑
      2. 使用的话 要想变量一样使用
      解决: 计算属性

4.书写思路

*首先我们分析下界面,通过sui把整体框架写好,

*我们分析下需求,从主体开始,有完成和删除,完成是通过背景的填充来体现的(点击事件来改变item.flag的值,而绑定样式button-fill就是通过item.flag来确定的);删除的话我们可以给一个删除事件,但是我们并不能删除还没有完成的任务,所以再删除之前,我们要确定这个任务是否已经完成,并来一个弹框来让用户确定,为了防止用户一不小心删除了未完成任务, 删除我们需要确定要删除哪一个,所以需要在remove()事件上传入参数index来确定删除哪一个,在检查时,如果任务已经完成,点击则删除,反之,则弹框提醒

*接下来我们考虑头部的添加任务,可以通过给一个按下事件,我们要考虑这几个方面。首先, 这个数据交互应该是双向的,而且一开始是看不见的,点击后出现,其次,在添加任务完成后 input框内容清空,input隐藏

*最后来解决底部,按需求来,A代表所有的展示,F表示已完成的,U表示未完成的, 我们先来一个type值,然后需要循环这个所有任务,通过来判断type是否与AFU相等来完成事件

例子

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Todo_list待办事项</title>
<link rel="stylesheet" href="https://g.alicdn.com/msui/sm/0.6.2/css/sm.min.css">
<link rel="stylesheet" href="./css/index.css">
<script type='text/javascript' src='https://g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script>
<script type='text/javascript' src='https://g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script>
</head>
<body>
<div id="app">
<div class="page-group">
<div class="page page-current">
<!-- header start-->
<header class="bar bar-nav">
<a class="icon icon-star pull-left"></a>
<a class="icon icon-edit pull-right"
@click='taskFlag=!taskFlag'
></a>
<h1 class="title"> TODO_LIST </h1>
</header>
<!-- header end-->
<!-- content start-->
<div class="content">
<!-- edit-start -->
<input type="text"
v-show='taskFlag'
v-model='task'
placeholder="请输入待办事项"
@keyup.enter='addTodos'
>
<!-- edit-end -->
<div
class="card"
v-for='(item,index) in newTodos'
>
<div class="card-content">
<div class="card-content-inner">{{item.text}}</div>
<div class="pull-right lcj-btn">
<button
class="button button-success"
@click='item.flag=!item.flag'
:class="{'button-fill':item.flag}"
>
<span class="icon icon-check"></span>
</button>
<button
class="button button-fill button-danger"
@click='check(index)'
>
<span class="icon icon-remove"></span>
</button>
</div>
</div>
</div>
</div>
<!-- content end-->
<!-- modal--start -->
<div
class='content'
v-show='maskFlag'
@click='maskFlag=false'
>
<div class="modal-overlay modal-overlay-visible"></div>
<div class="modal modal-in" style="display: block; margin-top: -72px;">
<div class="modal-inner">
<div class="modal-title">主人</div>
<div class="modal-text">您舍得离开我吗</div>
</div>
<div class="modal-buttons ">
<span
class="modal-button modal-button-bold"
@click='remove(activeIndex)'
>确定</span>
</div>
</div>
</div>
<!-- modal--end -->
<!-- footer start-->
<footer class="todos-footer">
<ul>
<li v-for='item in btnlist'>
<button
class="button"
:class="['button-'+item.className,type===item.text?'button-fill':'']"
@click='type=item.text'
>
{{item.text}}
</button>
</li>
</ul>
</footer>
<!-- footer start-->
</div>
</div>
</div>
</body>
<script src="../../basic-source/vue.js"></script>
<script src="../04.todolist/js/index.js"></script>
</html>

js代码

new Vue({
el:'#app',
data:{
todos:[
{
id: 1,
text: '撸猫',
flag: false,
},
{
id: 2,
text: '备课',
flag: false
}
],
task:'',
taskFlag:false,
maskFlag:false,
activeIndex:0,
type:'A',
btnlist:[
{
id:1,
text:'A',
className:'success'
},
{
id:1,
text:'F',
className:'primary'
},
{
id:1,
text:'U',
className:'danger'
},
]
},
methods:{
//添加一条待办事项
addTodos(){
this.todos.push({
id:this.todos.length+1,//这里不是很正确,
text:this.task,
flag:true,
})
this.task='',//添加后需要让input内容为空
this.taskFlag=false//添加后需要把input重新隐藏
},
//再删除前得判断事件是否完成
check(index){
if(this.todos[index].flag){
this.remove(index)
}else{
this.activeIndex=index,
this.maskFlag=true
}
},
//删除,因为不能直接拿到下标,只能传入参数
remove(index){
this.todos.splice(index,1)
},
},
computed:{
newTodos(){
if(this.type==='A'){
return this.todos
}else if(this.type==='F'){
return this.todos.filter((item,index)=>{
return item.flag?item:null
})
}else{
return this.todos.filter((item,index)=>{
return !item.flag?item:null
})
}
}
}
})

css样式

*{
margin: 0;
padding: 0;
list-style: none;
}
.lcj-btn{
display: flex;
}
.lcj-btn button{
margin-right: 10px;
}
.card{
overflow: hidden;
padding-bottom: 10px;
}
.todos-footer{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 100px;
}
.todos-footer ul{
display: flex;
justify-content: space-around;
}
.todos-footer li{
width: 80px;
height: 80px;
}
.todos-footer li button{
width: 100%;
height: 100%;
border-radius:50%
}


猜你喜欢

转载自blog.csdn.net/weixin_44889992/article/details/89389652