文章目录
一. 利用optionAPI实现 todoList功能
需求分析:
模块1:按照目标网站一样涉及整个页面内容
模块2: 输入模块, doing模块 done模块
模块3:done可以反向到 doing
模块4:注意细节的实现 例如可以删除时间,可以统计数字。
功能类似如下:
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 效果展示、
二. 利用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 效果展示
三.总结
本次练习了利用optionAPI 与 compositionAPI 分别实现 todoList功能。收获很大,极大的巩固了子父组件传值的使用。