实现功能如下:
1:创建一个任务List
2:删除一至多个任务list
3:全选/反选任务list
具体实现过程如下:
一、创建静态的框架
<文本>
//<myHeader>部分
<div>
<input type="text" placeholder="请输入你的任务名称,并且按回车确认"
v-model="inputList"
@keyup.enter="submit" >
</div>
//<myBody>部分
<div>
<ul>
<li v-for="p in toDoLists" :key="p.id" class="Items">
<input type="checkbox" :checked="p.checked" :value="p.task" @click="ChangeBox(p.id)">
<span>{{ p.task }}</span>
<button @click="DeleteList">删除</button>
</li>
</ul>
</div>
//<myFooter>部分
<div class='myFooter'>
<input type="checkbox" id="done" :checked="isChoose" @click="AlterBlanket()">
<label for="done">已完成{{ doneNum }}/全部{{ totalNum }}</label>
</div>
<css样式>
//<myHeader>部分
input{
width: 300px;
height: 20px;
outline: none;
border-width: 0.5px 1px 1px;
border: rgb(243, 243, 243) solid
}
input:focus{
outline: none;
border:1px black solid
}
//<myBody>部分
button {
color: red;
float: right;
display: none;
}
.Items {
width: 304px;
height: 25px;
border: solid rgb(243, 243, 243);
border-width: 0.5px 1px 1px;
}
ul {
list-style-type: none;
padding: 0px;
margin: 0px;
}
.Items:hover button {
/* 通过光标的移动位置来添加 btn 的显示效果 */
display: block;
}
//<myFooter>部分
label {
padding-left: 10px;
}
.myFooter {
width: 300px;
height: 20px;
border: 1px solid rgb(243, 243, 243);
}
二、创建交互
//<myHeader>部分----->创建一个任务List --->全选/反选任务list
data() {
return {
inputList: '',
temp: { id:'', task: '', checked: '' },// 传递给my-Body的一个中转变量
checkId: '1'
}
},
methods: {
submit() {
if (this.inputList) {
this.temp.id = nanoid()
this.temp.task = this.inputList
this.temp.checked = false
this.$bus.$emit('sendToBody', this.temp)
this.inputList = '' // 确定之后 将输入框中的值 置零
this.temp = {}
}
}
}
//<myBody>部分 ---->删除一至多个任务list
data() {
return {
allLists: [], //所有的任务
toDoLists: [], //等待完成的任务
doneLists: [], //已经完成的任务
tempLists: [], //选中的任务,并未删除,准备删除或者取消删除
mountNum: { totalNum: '0', DoneNum: '0' },
isChoose: '', //来自footer的不一定要进行赋值调用
}
},
// 首先是数据初始化,接收来自my-Header的任务信息
mounted() {
this.$bus.$on('sendToBody', (data) => { //console.log(data);
this.allLists.unshift(data) // 添加任务到所有的任务中
this.toDoLists.unshift(data) //添加新任务到待完成任务中
this.mountNum.totalNum = this.allLists.length
this.$bus.$emit('sentToFooter', this.mountNum)
})
},
methods: {
ChangeBox(x) { // 可以用来传递点击的当前id console.log(x);
// console.log(x);
this.tempLists = []
for (let i = 0; i < this.toDoLists.length; i++) {
if (this.toDoLists[i].id.indexOf(x) == 0) { //找到点击选择框后的id
this.toDoLists[i].checked = !this.toDoLists[i].checked
}
if (this.toDoLists[i].checked) {
this.tempLists.push(this.toDoLists[i]) //选中的任务,并未删除,准备删除或者取消删除
}
}
},
DeleteList() {
for (let i = 0; i < this.tempLists.length; i++) {
this.doneLists.unshift(this.tempLists[i]) //顺便把此时的中转添加到已完成中
this.toDoLists = this.toDoLists.filter(p => {
return p.id.indexOf(this.tempLists[i].id)
})
}
this.mountNum.DoneNum = this.doneLists.length
this.$bus.$emit('sentToFooter', this.mountNum) // 删除完,更新已完成数据
},
AllChoose(x) {
let temp = this.toDoLists
this.toDoLists = []
// console.log(temp);
for (let i = 0; i < temp.length; i++) {
temp[i].checked = x // 选中所有的todoLists
}
this.toDoLists = temp
x == true ? this.tempLists = this.toDoLists : this.tempLists = []
}
}
//<myFooter>部分
name: 'myFooter',
props: {
ChooseBodyLists: {
type: Function,
required: true
}
},
data() {
return {
doneNum: '0', // 已完成数目
totalNum: '0', // 总任务数目
isChoose: false // 是否全选,这个数据通过父子组件传给my-Body
// 这个数据尚未传输
}
},
methods: {
AlterBlanket() {
this.isChoose = !this.isChoose
// this.$emit('ChooseBodyLists')
this.ChooseBodyLists(this.isChoose)
}
},
mounted() {
// 接收来自 my-Body 的 数据(总数和已完成数目)
this.$bus.$on('sentToFooter', (data) => {
this.doneNum = data.DoneNum;
this.totalNum = data.totalNum;
if(this.doneNum==this.totalNum){
this.isChoose = true
}
})
}
APP组件部分
<div>
<my-header></my-header>
<my-body ref="BodyChoose"></my-body>
<my-footer :ChooseBodyLists="trans"></my-footer>
</div>
methods: {
trans(x){
this.$refs.BodyChoose.AllChoose(x)
}
},
三、最终结果
to-do-list