子组件写好之后,需要在父组件中引用
所以在script中
导入:
import lists from './list'
申明:
components:{
"lists":lists,
},
-------------------------------------------
先来看一下数据的定义
data() {//数据初始化
return {
things:[],
whichshow:true,
defaultshow:true,
dataStatus:["All","Active","Completed"],
dataStatusIndex:0,
}
},
things是空的数组,用来存储输入的每一个对象,然后传入子组件
whichshow和defaultshow也就是上一篇讲的用来控制显示全部还是未完成还是已完成的值,用来传入子组件
dataStatus是一个数组,是三个按钮的名字
dataStatusIndex存储三个按钮的序号
--------------------------------------
先来看页面部分,第一部分是输入部分
<div>
<div class="icon-down">
<span class="el-icon-arrow-down" @click="selectAllTodos"></span>
</div>
<input type="text" class="todos_add" placeholder=" What needs to be done ?"
ref="currentInput" @keyup.enter="addTodo($event.target)">
</div>
span是一个按钮,用来控制全部选择或者反选的,、
class是element组件,@click就是单击出发方法selectAllTodos
selectAllTodos() {
this.isChecked=!this.isChecked
this.things.map(todo => todo.isChecked=this.isChecked)
},
第一行的意思是如果list被打勾,那么变成不打勾,如果list不打勾那么变成打勾,也就是实现了全选和反选
第二行,遍历数组things,将改变的isChecked的值赋给每一个list
----------
input就是输入你要做的todo
ref的值就是设立一个值,后面调用来使输入完毕后清空输入框
@keyup.enter就是按下键盘enter键后执行addTodo方法
addTodo:function(e) {
var val=e.value
if(val==="")
{
return
}
this.things=this.things.concat({
value:val,
isChecked:false,
isEditing:false
})
this.$refs.currentInput.value=""
},
concat就是数组拼接,也就是增加一个含有value,isChecked,isEditing的对象
----------------------------------------------------------------------------------------------
第二部分,调用子组件
<lists :things1="things" :whichshow="whichshow" :defaultshow="defaultshow" ></lists>
三个属性就是将三个数据传入到子组件中
-----------------------------------------------------------------------------------------------
第三部分就是控制部分
<div v-show="things.length>0" class="data">
<div v-show="times >= 0" class="data_times">
<span>{{times}}</span> items left
</div>
<div class="data_status">
<a href="#" :class="{active:index===dataStatusIndex}" v-for="(item,index) in dataStatus" @click="switchStatus(index)" :key="index">
{{item}}
</a>
</div>
<div @click="clearTodos" v-show="times<things.length" class="data_clearTodos">
<a href="#" >clear completed</a>
</div>
<div @click="clearTodos" v-show="times === things.length" class="data_clearTodos">
<a href="#" style="border:none"></a>
</div>
</div>
大div中,v-show就是当things中有数据则显示
<div v-show="times >= 0" class="data_times">
<span>{{times}}</span> items left
</div>
控制部分中第一个是显示有多少条需要做的todo
times是一个计数器
computed:{
times() {
let todoArr=this.things
let times=0
for(let i=0;i<todoArr.length;i++) {
if(todoArr[i].isChecked===false) {
times++
}
}
return times
}
},
第二个就是显示三个按钮,点击按钮触发不同的显示
<div class="data_status">
<a href="#" :class="{active:index===dataStatusIndex}" v-for="(item,index) in dataStatus" @click="switchStatus(index)" :key="index">
{{item}}
</a>
</div>
也比较简单吧,循环输出dataStatus数组中的值,也就是三个按钮的名字
单击触发switchStatus方法
switchStatus(index) {
this.dataStatusIndex=index
if(this.dataStatus[index]==="Active") {
this.defaultshow=false
this.whichshow=false
}
else if(this.dataStatus[index]==="Completed") {
this.defaultshow=false
this.whichshow=true
}
else if(this.dataStatus[index]==="All") {
this.defaultshow=true
}
},
不同的按钮,改变不同的defaultshow和whichshow
最后一个部分是清除完成的todo
<div @click="clearTodos" v-show="times<things.length" class="data_clearTodos">
<a href="#" >clear completed</a>
</div>
<div @click="clearTodos" v-show="times === things.length" class="data_clearTodos">
<a href="#" style="border:none"></a>
</div>
这两个div一个是显示clear completed,一个是空白
空白是因为利用的flex布局,如果不占有一个空间的话,布局会乱,因为三个DIV的布局,和两个DIV的布局不一样
点击出发clearTodos方法
clearTodos() {
this.things=this.things.filter(todo => todo.isChecked == false)
},
将isChecked等于dalse的todo从数组中删除
附上完成代码:
<template>
<div class="content" id="app">
<div>
<div class="icon-down">
<span class="el-icon-arrow-down" @click="selectAllTodos"></span>
</div>
<input type="text" class="todos_add" placeholder=" What needs to be done ?"
ref="currentInput" @keyup.enter="addTodo($event.target)">
</div>
<lists :things1="things" :whichshow="whichshow" :defaultshow="defaultshow" ></lists>
<div v-show="things.length>0" class="data">
<div v-show="times >= 0" class="data_times">
<span>{{times}}</span> items left
</div>
<div class="data_status">
<a href="#" :class="{active:index===dataStatusIndex}" v-for="(item,index) in dataStatus" @click="switchStatus(index)" :key="index">
{{item}}
</a>
</div>
<div @click="clearTodos" v-show="times<things.length" class="data_clearTodos">
<a href="#" >clear completed</a>
</div>
<div @click="clearTodos" v-show="times === things.length" class="data_clearTodos">
<a href="#" style="border:none"></a>
</div>
</div>
<!-- <div>
<a href="./page" >turnother</a>
</div> -->
</div>
</template>
<script>
import lists from './list'
export default {
name:'app',
data() {//数据初始化
return {
things:[],
whichshow:true,
defaultshow:true,
dataStatus:["All","Active","Completed"],
dataStatusIndex:0,
}
},
components:{
"lists":lists,
},
methods:{
selectAllTodos() {
this.isChecked=!this.isChecked
this.things.map(todo => todo.isChecked=this.isChecked)
},
addTodo:function(e) {
var val=e.value
if(val==="")
{
return
}
this.things=this.things.concat({
value:val,
isChecked:false,
isEditing:false
})
this.$refs.currentInput.value=""
},
switchStatus(index) {
this.dataStatusIndex=index
if(this.dataStatus[index]==="Active") {
this.defaultshow=false
this.whichshow=false
}
else if(this.dataStatus[index]==="Completed") {
this.defaultshow=false
this.whichshow=true
}
else if(this.dataStatus[index]==="All") {
this.defaultshow=true
}
},
clearTodos() {
this.things=this.things.filter(todo => todo.isChecked == false)
},
},
computed:{
times() {
let todoArr=this.things
let times=0
for(let i=0;i<todoArr.length;i++) {
if(todoArr[i].isChecked===false) {
times++
}
}
return times
}
},
}
</script>
<style>
.content {
width: 440px;
display: flex;
justify-content: center;
flex-direction: column;
margin: 0 auto;
}
.todos_add {
width: 400px;
height: 40px;
font-size: 20px;
}
.icon-down {
float: left;
padding: 0;
margin: 0;
box-sizing: border-box;
border: 1px solid gray;
width:36px;
height: 46px;
padding-top: 15px;
}
</style>