效果图:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小目标列表</title>
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
<style>
body{
font-family: 微软雅黑;
}
ul{
list-style: none;
}
#list{
width: 400px;
margin: 50px auto;
}
.in-enter{
width: 200px;
height: 30px;
padding-left: 10px;
border-radius: 5px;
border: 1px solid #c3c3c3;
margin-bottom: 5px;
}
.radio{
margin: 5px 0;
}
.deleteIcon{
display: none;
float: right;
}
i:hover{
cursor: pointer;
}
li{
padding: 3px 15px;
}
li:hover{
border: 1px solid #9dc8e6;
}
li:hover .deleteIcon{
display: inline-block;
}
.edit>div{
display: none;
}
li>input{
display: none;
}
.edit input{
display: block;
width: 200px;
height: 20px;
padding-left: 10px;
border-radius: 5px;
border:none;
}
</style>
</head>
<body>
<div id="list">
<h3>小目标列表</h3>
<h4>添加小目标</h4>
<input class="in-enter" type="text" placeholder="输入小目标后,按回车确认" v-model="addText" @keyup.13="addList"></br>
<span>共有{{goalList.length}}个小目标,{{noFinishNum==0 ? '全部完成':'已完成'+(goalList.length-noFinishNum)+'个目标,还有'+noFinishNum+'个目标'}}</span></br>
<div class="radio">
<input type="radio" name="radio" id="radio1" checked @click="chooseList(1)"><label for="radio1">所有目标</label>
<input type="radio" name="radio" id="radio2" @click="chooseList(2)"><label for="radio2">已完成目标</label>
<input type="radio" name="radio" id="radio3" @click="chooseList(3)"><label for="radio3">未完成目标</label>
</div>
<ul>
<li v-for="(list,index) in newList" :class="{'edit':curIndex===index}">
<div>
<i class="fa" @click="changeStatus(list)" :class="list.status ? 'fa-check-square-o':'fa-square-o'"></i>
<span @dblclick="curIndex=index">{{list.name}}</span>
<i class="fa fa-times deleteIcon" @click="deleteList(index)"></i>
</div>
<input type="text" v-model="list.name" v-focus @keyup.esc="cancelEdit(list)" @focus="editBefore(list.name)" @blur="edited" @keyup.enter="edited">
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.4.2/dist/vue.js"></script>
<script>
Vue.directive('focus', {
// 当绑定元素插入到 DOM 中。
focus: function (el) {
// 聚焦元素
el.focus()
},
});
new Vue({
el:'#list',
data:{
addText:'',
curIndex:'',
curType:1,
beforeName:'',
goalList:[
{
name:'HTML',status:true
},
{
name:'CSS',status:false
},
{
name:'JS',status:false
}
],
newList:[]
},
computed:{
noFinishNum:function () {
return this.goalList.filter(function (item) {return !item.status}).length;
}
},
methods:{
addList:function () {
this.goalList.push(
{
name:this.addText,
status:false
});
this.addText=''
},
chooseList:function (type) {
this.curType=type;
switch (type) {
case 1:this.newList=this.goalList;break;
case 2:this.newList=this.goalList.filter(function (item) {return item.status});break;
case 3:this.newList=this.goalList.filter(function (item) {return !item.status});break;
}
},
editBefore:function(name){
this.beforeName=name;
},
cancelEdit:function(list){
list.name=this.beforeName;
this.curIndex='';
},
deleteList:function (index) {
this.goalList.splice(index,1);
this.newList=this.goalList;
},
edited:function () {
this.curIndex='';
},
changeStatus:function(list){
list.status=!list.status;
this.chooseList(this.curType);
},
},
mounted:function () {
this.newList=this.goalList;
},
directives:{
"focus":{
update(el){
el.focus();
}
}
}
})
</script>
</div>
</body>
</html>