TodoList
静态组件
OptionItem为OptionList的子组件。
FooterItem、HeaderItem、OptionList为App子组件
初始化列表
目前把数据放进OptionList里,子组件item通过props接收数据。
List:
<template>
<ul class="todo-main">
<!--eslint-disable-next-line vue/valid-v-for-->
<option-item v-for="todoobj in todos" :key="todoobj.id" :todo="todoobj"></option-item>
</ul>
</template>
<script>
import OptionItem from "./OptionItem.vue";
export default {
name: "OptionList",
data() {
return {
todos:[
{id:"001",title:'吃饭',done:true},
{id:"002",title:'睡觉',done:true},
{id:"003",title:'喝水',done:false},
],
};
},
components: {
// eslint-disable-next-line vue/no-unused-components
OptionItem,
},
};
</script>
Item”:
<template>
<li>
<label>
<input type="checkbox" :checked="todo.done"/>
<span>{
{todo.title}}</span>
</label>
<button class="btn btn-danger" style="display: none">删除</button>
</li>
</template>
<script>
export default {
name: "OptionItem",
data() {
return {
};
},
//接收数据todo对象
props:["todo"],
};
</script>
添加
目前需要Header和List之间传输数据,目前没有方法做到。
需要借用App组件。
子传父,父配置方法methods,并在模板中传入,子组件接收并调用方法。(引用传递)
父传子,父配置数据,并在模板中传入,子组件接收(propps)接收数据,再传递给子子组件。
子组件里面的数据想要传给父组件需要前提父组件先定义一个函数方法并且将这个函数方法传给子组件,然后子组件的数据代入为函数形参,这样父组件就可以有子组件的数据了
*Vue props传入function时的this指向问题
- props传入function时,函数中this自动绑定Vue实例;
- 在H5的Vue中项目中,console将输出 “this is parent.”;
但在uni-app小程序中使用Vue时,console将输出“this is child”;
Vue中不推荐向子组件传递Function的方式,因为Vue有更好的事件父子组件通信机制;
在Header里添加一个数据时, 调用addTodo,App里的数据变化,模板重新解析,然后把新的todos交给list,list收到数据,重新解析模板,生成4个item,diff算法新旧dom对比,传出todoobj,item获取todoobj,解析数据。
App.vue
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<header-item :addTodo='addTodo'></header-item>
<option-list :todos='todos'></option-list>
<footer-item></footer-item>
</div>
</div>
</div>
</template>
<script>
import HeaderItem from "./components/HeaderItem.vue";
import FooterItem from "./components/FooterItem.vue";
import OptionList from "./components/OptionList.vue";
export default {
name: "App",
data() {
return {
todos:[
{id:"001",title:'吃饭',done:true},
{id:"002",title:'睡觉',done:true},
{id:"003",title:'喝水',done:false},
],
};
},
components: {
// eslint-disable-next-line vue/no-unused-components
HeaderItem,
// eslint-disable-next-line vue/no-unused-components
FooterItem,
// eslint-disable-next-line vue/no-unused-components
OptionList,
},
methods: {
addTodo(obj){
this.todos.unshift(obj);
}
},
};
</script>
header.vue
<template>
<div class="todo-header">
<input type="text" placeholder="请输入你的任务名称,按回车键确认" v-model="title" @keyup.enter="add" />
</div>
</template>
<script>
import {nanoid} from 'nanoid';
e