一、前言
上期用最简单技术形式走通了前后台的需求,制作了一个任务管理系统,方便记录并规划每天的成长。
写任务的核心是为了更好的规划时间,想象让你做一个计划系统你该如何考虑?
1)首先你必须有地方去写,有地方展示
2)展示时需区别未完成和已完成的状态
3)需要规定一个结束日期,并且加入提醒,到指定时间未完成的任务,需要写清理由。
4)......
所以这期做一下调整:
1. 整体界面需要重新修改
2.PHP从面向过程升级成面向对象
3.删除接口从物理删除变为逻辑删除
4.因布局调整所影响前端逻辑的改良
5.基础SQL语法举一反三
二、调整样式
三、业务梳理
前端逻辑主要是练习vue基本语法,以及事件触发之间的逻辑关系,如何跟php交互数据。
主要功能:
用户输入添加后变为待办项,完成后用户勾选变为已办项,每一项计划可删除和编辑,还记录了计划的条数和未完成的条数
四、前端布局
上期的布局及样式完全推倒重做,代码如下:
<div class="hello"
id="box">
<h4>任务便签</h4>
<p style="font-size:12px;">总数为 <span style="color:#35b96d;">{{ arr.length}}</span>个,还有 <span style="color:#35b96d;">{{ choose() }}</span>个未完成</p>
<p style="font-size:12px; text-align: right;">【<span style="color:#35b96d;"
class="span1"
@click='finish()'>清除已选</span>】【<span class="span1"
@click='Allfinish()'
style="color:#35b96d;">全部清除</span>】</p>
<ul>
<li v-for="(item,index) in arr"
v-bind:class='{finish: item.bol}'>
<span class="icon_num">{{index+1}}</span>
<input type="checkbox"
v-model='item.bol'
@change="updataFn()"></input>
<span v-text='item.des'
v-show='!item.edit'
@click='edit(index)'></span>
<input type="text"
v-model='item.des'
v-show='item.edit'
v-on:keyup.13='item.edit = !item.edit'
@blur='item.edit = false;updataFn()'>
<span class="redStyle delBtn"
@click='del(item.des)'></span>
</li>
</ul>
<textarea placeholder="安排新的任务吧"
type="text"
class="add"
v-model='msg'
v-on:keyup.13="add"></textarea><button @click='add()'>保存</button>
</div>
-------------------------------------------------------------------------------------------------------------------
export default {
name: 'HelloWorld',
data () {
return {
arr: [
// 数据结构:
// des: 任务描述
// bol: 任务完成标志
// edit: 任务编辑标志
// { des:'设计', bol:false, edit:false }
],
msg: ''
}
},
created () {
if (localStorage.getItem('msg')) {
//如果有就读取msg存到arr数组中
this.arr = JSON.parse(localStorage.getItem('msg'))
}
},
methods: {
// 添加(判断msg是否为空,如果不为空就给arr数组里push内容,然后在把msg设置为空)
add: function () {
if (this.msg.replace(/[\r\n]/g, "") == '') {
this.msg = ''
alert('请输入名称');
return;
} else {
for (var i = 0; i < this.arr.length; i++) {
if (this.arr[i].des == this.msg.replace(/[\r\n]/g, "")) {
this.msg = ''
alert('任务名称不能重复');
return;
}
}
}
this.arr.push({ des: this.msg.replace(/[\r\n]/g, ""), bol: false, edit: false });
localStorage.setItem('msg', JSON.stringify(this.arr))
this.msg = ''
},
//更新到本地存储中
updataFn: function () {
localStorage.setItem('msg', JSON.stringify(this.arr))
},
// 返回未完成的数量
choose: function () {
var num = 0; // 未完成的数量
this.arr.forEach(function (item) {
if (!item.bol) {
num += 1;
}
});
return num;
},
// 返回未完成的任务
finish: function () {
var forNum = 0;
for (var i = 0; i < this.arr.length; i++) {
if (this.arr[i].bol) {
forNum++
}
}
if (forNum == 0) {
alert('您需要选中复选框删除');
}
var temp = this.arr;
this.arr = []
for (var i = 0; i < temp.length; i++) {
if (!temp[i].bol) {
this.arr.push(temp[i]);
console.log(temp[i])
}
}
this.updataFn();
},
//单条删除
del (des) {
var index = this.arr.findIndex(item => {
if (item.des == des) {
return true
}
})
this.arr.splice(index, 1)
this.updataFn();
},
//清除每条数据
Allfinish () {
if (this.arr.length == 0) {
alert('没有可删除的选项')
} else {
this.arr = [];
this.updataFn();
}
},
// 编辑
edit: function (i) {
if (this.arr[i].bol) {
return;
}
this.arr[i].edit = true;
}
}
}
</script>
--------------------------------------------------------------------------------------------------------------
.redStyle{background:#ccc;display:inline-block;width:20px;height:20px;vertical-align:middle}
h4{color:#252434}
.delBtn{margin-top:15px;float:right;background:url(../../src/assets/del.png) no-repeat;background-size:60%;vertical-align:middle}
#box{width:580px;margin:30px auto;background:#fff;color:#222131;padding:30px 50px;border:1px solid #252434;border-bottom-width:4px;border-radius:3px;font-family:"Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei"}
li:nth-child(2n+2){margin-right:0}
.icon_num{opacity:.8;color:#fff;box-sizing:border-box;border-radius:100%;display:inline-block;background:#35b96d;font-size:11px;left:-5px;width:15px;height:15px;line-height:15px;vertical-align:middle;text-align:center;bottom:-8px;border-radius:100%}
input[type=text]{outline:0;width:100%;border:1px solid #f9f9f9}
li{position:relative;background:#fff;border:1px solid #ccc;border-radius:3px;box-sizing:border-box;padding:0 11px;list-style-type:none;width:47%;line-height:40px;font-size:14px;color:#5e5d6d;margin-bottom:10px;margin-right:16px;float:left;font-size:12px;overflow:hidden}
ul{padding-left:0;margin-top:30px;margin-bottom:20px;overflow:hidden}
.add{width:100%;height:80px;margin-right:10px;margin-bottom:5px;outline:0}
.span1{color:#87ceeb}
.finish{box-sizing:border-box;color:#ccc;text-decoration:line-through;height:40px;line-height:40px;background:#eee;font-size:14px;border:none}
textarea{border:1px solid #252434;font-family:"Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei";padding:5px 10px;box-sizing:border-box;background:#fff;color:#252434}
button{outline:0;width:100%;background:#252434;border:none;height:40px;color:#ccc}
五、后台逻辑
六、下期预告
⚠ 下期会增加定时提醒(包含声音和弹窗提示),历史查询和显示以天为单位。
⚠ 下期会增加删除的再次询问功能,避免误删。
⚠ 下期会调整修改的布局样式。
⚠ 下下期做一个响应式布局,来适配手机端、平板、pc端。
⚠ 下下期加入登录和注册功能,加入users表。