将网页中勾选与vc中的done进行绑定
不能使用v-model,因为props只可读不可改
获取勾选或者取消勾选事情的id
有以下两种方法:方法一:@click()
先在UserItem中绑定一个点击事件,获取todo上id
勾选上洗碗,就会在控制台输出它的id
方法二:@change()
将刚才的@click事件改为@change事件也是可以的
通使勾选框发生改变,触发change事件,如:取消勾选打代码事情,就可以看到控制台输出了它的id
、
通过id来改它的done
一般通过方法改数据,方法都是和数据在同一个文件上,所以我们要在app组件上加一个方法
然后我们要把这个方法传给UserItem,就是说我们要先把方法从app传给UserList,
在UserList用props接收,再从UserList传给UserItem
在UserItem用props接收,并且在handleCheck方法调用checkTodo方法
效果实现如下
勾选洗碗后vc的done也跟着变成true了
本结主要代码如下:
UserList.vue
<template>
<ul class="todo-main">
<UserItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj" :checkTodo="checkTodo" />
</ul>
</template>
<script>
// 引入组件
import UserItem from "./UserItem.vue";
export default {
name: "UserList",
components: { UserItem },
props: ["todos", "checkTodo"],
data() {
return {};
},
};
</script>
<style scoped>
/* main */
.todo-main {
/* background-color: aqua; */
border: 1px solid #ddd;
border-radius: 2px;
padding: 0;
}
.todo-empty {
height: 40px;
line-height: 40px;
border: 1px solid #ddd;
border-radius: 2px;
padding-left: 5px;
margin-top: 10px;
}
</style>
UserItem.vue
<template>
<li>
<label>
<input type="checkbox" :checked='todo.done' @change="handleCheck(todo.id)" />
<span>{{todo.title}}</span>
</label>
<button class="btn btn-danger" style="display: none">删除</button>
</li>
</template>
<script>
// 组件交互相关的代码(数据、方法等等)
export default {
name: "UserItem",
props: ["todo","checkTodo"],
methods: {
handleCheck(id) {
this.checkTodo(id)
},
}
};
</script>
<style scoped>
/* item */
li {
list-style: none;
height: 36px;
line-height: 36px;
padding: 0 5px;
border-bottom: 1px solid #ddd;
}
li label {
float: left;
/* 鼠标移到时是一只手的形状 */
cursor: pointer;
}
li label input {
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
cursor: pointer;
}
li button {
float: right;
display: none;
margin-top: 3px;
}
li:before {
content: initial;
}
li:last-child {
border-bottom: none;
}
</style>
App.vue
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<UserHeader :AddTodoObj="AddTodoObj" />
<UserList :todos="todos" :checkTodo="checkTodo" />
<UserFooter />
</div>
</div>
</div>
</template>
<script>
// 引入组件
import UserHeader from "./components/UserHeader.vue";
import UserList from "./components/UserList.vue";
import UserFooter from "./components/UserFooter.vue";
export default {
name: "App",
components: { UserHeader, UserList, UserFooter },
data() {
return {
todos: [
{ id: "001", title: "打代码", done: true },
{ id: "002", title: "看电视剧", done: true },
{ id: "003", title: "洗碗", done: false },
],
};
},
methods: {
// 添加一个todo
AddTodoObj(todoObj) {
this.todos.unshift(todoObj);
// console.log("我是App组件,我收到了数据", x);
},
// 勾选or取消勾选一个todo
checkTodo(id) {
this.todos.forEach((todo) => {
if (todo.id === id) todo.done = !todo.done;
});
},
},
};
</script>
<style>
/* base */
body {
background-color: #fff;
/* margin: 0; */
}
.todo-container {
width: 600px;
margin: 0 auto;
/* background-color: antiquewhite; */
}
.todo-container .todo-wrap {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
.btn {
display: inline-block;
padding: 4px 12px;
/* margin-bottom: 0; */
font-size: 14px;
/* line-height: 20px; */
/* text-align: center; */
/* vertical-align 用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐 方式 */
vertical-align: middle;
cursor: pointer;
box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
.btn:focus {
/* outline: none; */
}
.btn-danger {
color: #fff;
background-color: #da4f49;
border: 1px solid #bd362f;
}
.btn-danger:hover {
color: #fff;
background-color: #bd362f;
}
</style>