老杜Vue的Bug列表实战代码
老杜Vue的Bug列表实战代码
谢谢杜老师的vue教学视频,说的真的好好
各位亲爱的小伙伴,如果不能使用代码,请给我留言哈。
1、效果图
2、html代码(我自己写的,和杜老师的有些不同,不要纠结哈,基本是没错的)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>注册页面</title> <style> .{ margin: 0; padding: 0; } button{ border-radius: 5px; padding: 10px 30px; font-weight: 600; } button:hover{ cursor: pointer; } /* bugHeader */ .Header_input { border-radius: 10px; padding-left: 10px; } .Header_button{ background-color: pink; } /* List */ .List{ border: black 1px solid; border-collapse: collapse; } .List thead{ background-color: slateblue; border: black 1px solid; } .List thead th{ border: black 1px solid; color: white; } .List tbody tr{ border: black 1px solid; } .List tbody tr td{ border: black 1px solid; text-align: center; line-height: 40px; } .List button{ background-color: crimson; color: white; } /* fooler */ .fooler{ background-color: crimson; color: white; } .one{ width: 400px; } </style> </head> <body> <!-- BUGHeader --> <textarea class="Header_input" cols="70" rows="5" placeholder="请输入BUG描述信息"></textarea><br> <button class="Header_button">保存</button> <!-- BugList --> <table class="List""> <thead> <th>全选</th> <th class="one">bug描述</th> <th>操作</th> </thead> <tbody> <tr> <td><input type="checkbox" name="bugs"></td> <td>xxxxxxxx</td> <td><button>删除</button></td> </tr> <tr> <td><input type="checkbox" name="bugs"></td> <td>xxxxxxxx</td> <td><button>删除</button></td> </tr> <tr> <td><input type="checkbox" name="bugs"></td> <td>xxxxxxxx</td> <td><button>删除</button></td> </tr> </tbody> </table> <br> <!-- BugFooler --> <button class="fooler">清楚已解决</button>当前BUG总量2个,已解决1个 </body> </html>
App组件代码
<template> <div> <BugHeader :saveBugCallback="saveBugCallback"></BugHeader> <BugList :bugList="bugList" :modifyResolved="modifyResolved" :deleteById="deleteById" :selectAllCallBack="selectAllCallBack" :updateDescCallBack="updateDescCallBack"></BugList> <BugFooter :bugList="bugList" :clearResolvedCallBack="clearResolvedCallBack"></BugFooter> </div> </template> <script> import BugHeader from './components/BugHeader.vue' import BugList from './components/BugList.vue' import BugFooter from './components/BugFooter.vue' export default { components:{ BugHeader,BugList,BugFooter }, data(){ return{ bugList:[ {id:'001',desc:'Bug描述信息100',resolved:false}, {id:'002',desc:'Bug描述信息2',resolved:true}, {id:'003',desc:'Bug描述信息3',resolved:false} ] } }, methods:{ saveBugCallback(bug){ //保存bug对象的回调方法 this.bugList.unshift(bug) }, //改变多选框状态 modifyResolved(bugId){ this.bugList.forEach((bug)=>{ if(bug.id == bugId){ bug.resolved = !bug.resolved } }) }, //移除数据 deleteById(BugId){ this.bugList = this.bugList.filter((bug)=>{ return bug.id !== BugId }) }, //全选 selectAllCallBack(e){ this.bugList.forEach((bug)=>{ bug.resolved = e }) }, //删除选中的 clearResolvedCallBack(){ this.bugList = this.bugList.filter((bug)=>{ return bug.resolved == false }) }, //更新bug描述 updateDescCallBack(bugId,newDesc){ this.bugList.forEach((bug)=>{ if(bug.id == bugId){ bug.desc = newDesc // this.editState = false } }) } } } </script> <style> . { margin: 0; padding: 0; } button{ border-radius: 5px; padding: 10px 30px; font-weight: 600; } button:hover{ cursor: pointer; } </style>
BugHeader组件代码
<template>
<div>
<textarea v-model="desc" class="Header_input" cols="100" rows="5" placeholder="请输入BUG描述信息" @keydown.enter="saveBug"></textarea><br>
<button class="Header_button" @click="saveBug" >保存</button>
<br><br>
</div>
</template>
<script>
export default {
name:'BugHeader',
data(){
return {
desc:''
}
},
props:['saveBugCallback'],
methods:{
saveBug(){
console.log(this.desc)
//创建bug对象
let bugObj = {id:Date.now(),desc:this.desc,resolved:false}
//添加到bugList数组当中
if(bugObj.desc != ''){
this.saveBugCallback(bugObj)
}
}
}
}
</script>
<style scoped>
.Header_input {
border-radius: 10px;
padding-left: 10px;
}
.Header_button{
background-color: pink;
}
</style>
BugList组件代码
<template>
<div v-show="bugList.length">
<table class="List">
<thead>
<th>全选<input type="checkbox" :checked="isAll" @change="selectAll"></th>
<th class="one">bug描述</th>
<th>操作</th>
</thead>
<tbody>
<BugItem v-for="bug in bugList" :key="bug.id" :bug="bug" :modifyResolved="modifyResolved" :deleteById='deleteById' :updateDescCallBack="updateDescCallBack"></BugItem>
</tbody>
</table>
<br>
</div>
</template>
<script>
import BugItem from './BugItem.vue'
export default {
components:{BugItem},
props:['bugList','modifyResolved','deleteById','selectAllCallBack','updateDescCallBack'],
computed:{
resolvedCount(){
const count = this.bugList.reduce((a,b)=>{
return a + ( b.resolved? 1 : 0 )
},0)
return count
},
isAll(){
return this.bugList.length === this.resolvedCount && this.bugList.length != 0
}
},
methods:{
selectAll(e){
this.selectAllCallBack(e.target.checked)
}
}
}
</script>
<style scoped>
.List{
border: black 1px solid;
border-collapse: collapse;
}
.List thead{
background-color: slateblue;
border: black 1px solid;
}
.List thead th{
border: black 1px solid;
color: white;
}
</style>
BugItem代码
<template> <tr> <td><input type="checkbox" name="bugs" :checked="bug.resolved" @click="modifyRes(bug.id)"></td> <td> <span v-show="!bug.editState" class="desc" @click="enterEdit">{{ bug.desc }}</span> <input v-show="bug.editState" ref="inputDesc" type="text" :value="bug.desc" @blur="updateDesc"> </td> <td><button @click="delById(bug.id)">删除</button></td> </tr> </template> <script> export default { name:'BugItem', props:['bug','modifyResolved','deleteById','updateDescCallBack'], methods:{ modifyRes(bugId){ this.modifyResolved(bugId) }, delById(bugId){ this.deleteById(bugId) }, enterEdit(){ //往bug列表中添加一个新的属性 if(this.bug.hasOwnProperty('editState')){ this.bug.editState = true }else{ this.$set(this.bug,'editState',true) } this.$refs.inputDesc.focus() //获取文本框,并且让文本框获取到焦点 //第一种方案 // setTimeout(()=>{ // this.$refs.inputDesc.focus() // },1000) //第二种方案【使用Vue提供好的API就行了】 //非常重要:next方法会绑定一个回调函数,这个回调函数在 // 什么时候执行?在下一个DOM全部渲染完毕之后被调用 this.$nextTick(function(){ this.$refs.inputDesc.focus() }) }, updateDesc(e){ //获取最新的描述信息 let newDesc = e.target.value.trim() if(!newDesc)return this.updateDescCallBack(this.bug.id,newDesc) this.bug.editState = false } } } </script> <style scoped> .List tbody tr{ border: black 1px solid; } .List tbody tr td{ border: black 1px solid; text-align: center; line-height: 40px; } .List button{ background-color: crimson; color: white; } .desc{ cursor: pointer; } </style>
BugFooter代码
<template> <div v-show="bugList.length"> <button class="fooler" @click="clearResolved">清除已解决</button> <span>当前BUG总量{{bugList.length}}个,已解决{{resolvedCount}}个</span> </div> </template> <script> export default { props:['bugList','clearResolvedCallBack'], computed:{ resolvedCount(){ // 采用普通计数器的方式 // let count = 0 // this.bugList.forEach((bug)=>{ // if(bug.resolved){ // count++ // } // }) // return count //使用ES6数组的reduce方法进行对数组条件的统计 //this.bugList.reduce(回调函数,统计起点) //统计起点从0开始 //回调函数有两个参数:a,b //回调函数的调用次数和数组中元素总数有关系。数组中有三个元素,则这个回调函数被调用3次 //a是什么?a是上一次回调函数调用之后的返回值 //b是什么?当前被统计的对象 const count = this.bugList.reduce((a,b)=>{ return a + ( b.resolved? 1 : 0 ) },0) return count } }, methods:{ clearResolved(){ this.clearResolvedCallBack() } } } </script> <style scoped> .fooler{ background-color: crimson; color: white; } .one{ width: 400px; } </style>