利用optionAPI 与 compositionAPI 分别实现 todoList功能

一. 利用optionAPI实现 todoList功能

需求分析:

模块1:按照目标网站一样涉及整个页面内容

模块2: 输入模块, doing模块 done模块

模块3:done可以反向到 doing

模块4:注意细节的实现 例如可以删除时间,可以统计数字。

功能类似如下:

image-20230327091356478

1.1 ToDoList.vue 页面

1.创建一个新项目,在主入口内加入路由页面:

<router-link to="/todolist">todoList</router-link> |

2.路由设置:router

import todolist from '../views/ToDoList.vue'
{
    
    
    path:'/todolist',
    name:'todolist',
}

3.挂载子页面:

父页面:ToDoList.vue

子页面:AddList.vue、ListDoing.vue、DoneList.vue

<div>
    <add-list @goaddlist="toaddlist"></add-list>
    <list-doing @todolist="todolist" :list="dolist.list"></list-doing>
    <done-list @donelist="donelist" :list="dolist.list"></done-list>
    <hr />
</div>
··········
import AddList from "../components/AddList.vue";
import ListDoing from "../components/ListDoing.vue";
import DoneList from "../components/DoneList.vue";
··········
components: {
AddList,ListDoing,DoneList
},

上述代码实现:

引入子页面,并且挂载到页面中,并且放行。

设置数据,变量类型为列表对象。

data () {
    
    
    return {
    
    
        dolist:{
    
    
            list:[{
    
    text:'测试',doflag:0}]
        }
    };
},

1.2 AddList.vue页面

1.模板层:

<template>
   <div>
    <input type="text" v-model="addlist" />
    <button @click="handleAdd">添加</button>
   </div>
</template>

2.函数调用:(设置用户空字符拦截。将字符串传值给父页面($emit)

handleAdd(){
    
    
    if (this.addlist == "") {
    
    
        alert("不能为空");
        return;
    }
    this.$emit("goaddlist", this.addlist);
    this.newItem = "";
}

3.父页面接受子页面传值:

toaddlist(newtext){
    
    
    this.dolist.list.push({
    
    text:newtext,doflag:0});
    console.log(this.dolist.list);
},

对list对象进行追加。并且输出对象查看。

1.3 ListDoing.vue页面

1.模板层:

<template>
<div>
    <hr>
    <h1>待完成</h1>
    <ol>
        <div v-for="(item, index) in list" :key="index" @click.stop="judgeItem(index)">
            <li v-if="item.doflag == 0">
                {
   
   { item.text }} ··········· <button @click.stop="poplist(index)">删除</button>
    </li>
    </div>
    </ol>
    </div>
</template>

使用v-for循环输出列表对象,使用v-if进行判断渲染。

使用prpos父组件进行接受子组件传参。

props: {
    
    
    list: {
    
    
        type: Object,
            // required: true,
    },
},

方法层:

judgeItem(index) {
    
    
    console.log("执行已完成");
    this.list[index].doflag = 1
    this.$emit("todolist", this.list);
},
    poplist(index){
    
    
        this.list.splice(index,1)
        this.$emit("todolist", this.list);
    }

judgeItem:实现了对list列表对象里的doflag进行赋值改变:

0:未完成。1:已完成。将列表对象改变之后传值返回给父组件。

poplist:实现了删除操作,将列表对象的下标获取进行删除。将列表对象改变之后传值返回给父组件。

父组件接受传参:以上传参函数均为todolist。

将父组件里的列表对象重新赋值为子组件更改过之后的对象值。

todolist(newtext){
    
    
    this.dolist.list=newtext;
    console.log(this.dolist.list);
},

1.3 DoneList.vue页面

已完成的功能模块和未完成的功能模块基本相同。

1.模板层:

<template>
   <div>
    <hr>
      <h1>已完成</h1>
      <ol>
         <div v-for="(item, index) in list" :key="index" @click="judgeItem(index)">
            <li v-if="item.doflag == 1">
               {
   
   { item.text }} ··········· <button @click.stop="poplist(index)">删除</button>
            </li>
         </div>
      </ol>
   </div>
</template>

2.子组件获取到父组件的传参:

props: {
    
    
    list: {
    
    
        type: Object,
            // required: true,
    },
},

3.js功能层:

judgeItem(index) {
    
    
    this.list[index].doflag = 0
    this.$emit("todolist", this.list);
},
poplist(index){
    
    
        this.list.splice(index,1)
        this.$emit("todolist", this.list);
}

父组件的接受子组件传值函数于ListDoing.vue页面相同。

1.4 效果展示、

img

img

img

二. 利用compositionAPI 实现 todoList功能

父页面:ToDoListComposition.vue

子页面:CoAddList.vue、CoDoneList.vue、CoListDoing.vue

2.1 ToDoListComposition.vue页面

1.模板层:

<template>
    <div class="home">
        <co-add-list :dolist="dolist.list" @goaddlist="addlist" />
        <CoListDoing :dolist2="dolist.list"/>
        <coDoneList :dolist2="dolist.list"/>
    </div>
</template>

2.分别挂载三个子页面。

import {
    
     reactive, watchEffect } from 'vue';
import CoAddList from "../components/CoAddList.vue";
import CoListDoing from "../components/CoListDoing.vue";
import coDoneList from "../components/CoDoneList.vue";

3.使用响应式数据:reactive

const dolist = reactive({
    
    
    list: [{
    
     text: '测试', doflag: 0 }]
})

2.2 CoAddList.vue页面

1.模板层:

<template>
    <div>
        <input type="text" v-model="state.addlist" />
        <button @click="handleAdd">添加</button>
        {
   
   { dolist }}
    </div>
</template>

2.使用props进行父传子

props: {
    
    
        dolist: Object,
    },

3.使用reactive创建响应式数据。

setup(props, context) {
    
    
    const state = reactive({
    
    
        addlist: ""
    });
    function handleAdd() {
    
    
        if (state.addlist == "") {
    
    
            alert("不能为空");
            return;
        }
        // context.emit('goaddlist',1);
        context.emit("goaddlist", state.addlist);
        state.addlist = "";
    }
    return {
    
    
        state,
        handleAdd
    }
}

handleAdd函数的作用,进行空值判断。使用context.emit进行子传父值。

父组件:

const addlist = (value) => {
    
    
    dolist.list.push({
    
     text: value, doflag: 0 });
    console.log(dolist.list);
}

进行传值覆盖。

2.3 CoListDoing.vue页面

模板层:

<template>
<div>
    <hr>
    <h1>待完成</h1>
    <ol>
        <div v-for="(item, index) in dolist2" :key="index" @click.stop="judgeItem(index)">
            <li v-if="item.doflag == 0">
                {
   
   { item.text }} ··········· <button @click.stop="poplist(index)">删除</button>
    </li>
    </div>
    </ol>
    </div>
</template>

思路和实现几乎于optionAPI相同。

poplist:用于删除数据。 judgeItem:用于点击状态识别改变。

import {
    
     reactive, computed, emit, defineProps } from "vue";
export default {
    
    
    setup(props, context) {
    
    
        const state = reactive({
    
    
            addlist: ""
        });
        function poplist(index) {
    
    
            props.dolist2.splice(index, 1)
            // props.$emit("todolist", this.list);
            context.emit("todolist", state.dolist2);
        }
        function judgeItem(index) {
    
    
            console.log("执行已完成");
            props.dolist2[index].doflag = 1
            context.emit("todolist", state.dolist2);
        }
        return {
    
    
            state, poplist,judgeItem
        }
    }, props: {
    
    
        dolist2: {
    
    
            type: Object,
            required: true,
        },
    }
}

1.4 CoDoneList.vue页面

页面:

<template>
<div>
    <hr>
    <h1>待完成</h1>
    <ol>
        <div v-for="(item, index) in dolist2" :key="index" @click.stop="judgeItem(index)">
            <li v-if="item.doflag == 1">
                {
   
   { item.text }} ··········· <button @click.stop="poplist(index)">删除</button>
    </li>
    </div>
    </ol>
    </div>
</template>

JS代码:

import {
    
     reactive, computed, emit, defineProps } from "vue";

export default {
    
    
    setup(props, context) {
    
    
        const state = reactive({
    
    
            addlist: ""
        });

        function poplist(index) {
    
    
            props.dolist2.splice(index, 1)
            context.emit("todolist", state.dolist2);
        }

        function judgeItem(index) {
    
    
            console.log("执行已完成");
            props.dolist2[index].doflag = 0
            context.emit("todolist", state.dolist2);
        }
        return {
    
    
            state, poplist,judgeItem
        }
    }, props: {
    
    
        dolist2: {
    
    
            type: Object,
            required: true,
        },
    }
}

1.5 效果展示

img

img

img

三.总结

本次练习了利用optionAPI 与 compositionAPI 分别实现 todoList功能。收获很大,极大的巩固了子父组件传值的使用。

猜你喜欢

转载自blog.csdn.net/weixin_52908342/article/details/129790428