三、父组件index的编写

子组件写好之后,需要在父组件中引用

所以在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>





阅读更多
文章标签: vue todolist
个人分类: Vue实现todolist MVC
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭