【发布时间】:2019-06-19 11:21:00
【问题描述】:
我有一个父组件(todo-list),里面有一个子组件(todo-item)。我正在尝试在父级中创建一个复选框(检查所有待办事项),以便一键检查所有待办事项。
在父组件中使用 checkAll(),它改变了子组件的 props,但它不改变子组件的数据。
这是父组件 todo-list
<template>
<div class="todo-list-container">
<todo-input @addTodo="addTodo"></todo-input>
<todo-item v-for="(todo, index) in todos"
:key="todo.id"
:todo="todo"
:index="index"
:completed="todo.completed"
@removeTodo="removeTodo"
@changedCompleted="changedCompleted"
></todo-item>
<div class="flex-container">
<div class="button-aux-div"></div>
<a href="#" class="todo-button">
<input type="checkbox" :checked="!anyRemaining" @change="checkAll">
</a>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import TodoItem from './TodoItem'
import TodoInput from './TodoInput'
export default {
name: 'todo-list',
components: {
TodoItem,
TodoInput,
},
data () {
return {
idForTodo: 3,
todos: [
{
'id': '1',
'title': 'title1',
'body': 'body1',
'completed': false,
},
{
'id': '2',
'title': 'title2',
'body': 'body2',
'completed': false,
},
],
allChecked: false,
}
},
computed: {
remaining() {
return this.todos.filter(todo => !todo.completed).length
},
anyRemaining() {
return this.remaining != 0
}
},
methods: {
addTodo(todoMessage) {
this.todos.push({
id: this.idForTodo,
title: 'title' + this.idForTodo,
body: todoMessage,
completed: false,
})
this.idForTodo++;
},
removeTodo(data) {
this.todos.splice(data.index, 1);
this.idForTodo--;
},
changedCompleted(data) {
this.todos.splice(data.index, 1, data.todo)
},
checkAll() {
this.todos.forEach((todo) => todo.completed = event.target.checked)
},
},
}
</script>
这是子组件 todo-item
<template>
<div class="todo-item-container">
<div class="todo-title-container">
<div class="todo-id-container">
<div id="todo-id">
<h2>{{ id }}</h2>
</div>
</div>
<div id="todo-title"><h2>{{ title }}</h2></div>
<div class="todo-completed-container">
<a href="#" class="todo-button">
<input type="checkbox" v-model="completed" @change="changedCompleted">
</a>
</div>
<div class="todo-delete-container">
<a href="#" class="todo-button" @click="deletedTodo">×</a>
</div>
</div>
<hr>
<div class="todo-body-container">
<p id="todo-body">{{ body }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props: {
todo : {
type: Object,
required: true,
},
index : {
type: Number,
required: true,
},
},
data () {
return {
'id': this.todo.id,
'title': this.todo.title,
'body': this.todo.body,
'completed': this.todo.completed,
}
},
methods: {
deletedTodo() {
this.$emit('removeTodo', {
'index': this.index,
'todo': {
'id': this.id,
'title': this.title,
'body': this.body,
'completed': this.completed,
}
})
},
changedCompleted() {
this.$emit('changedCompleted', {
'index': this.index,
'todo': {
'id': this.id,
'title': this.title,
'body': this.body,
'completed': this.completed,
}
})
},
},
}
</script>
【问题讨论】:
-
我没有看到 -
completed道具被child-component接收 -
@subhasis 下面建议添加一个计算属性。但是我需要将完成的道具从父母传给孩子吗?因为它已经包含在待办事项中。
-
props是响应式的,您不需要将其放入computed。它可能在这里不起作用,因为object是参考值,并且您正在传递对象的地址,因此内部的任何更新都需要得到深入关注。现在 - 如果您将completed属性传递给child并且每当completed获取更新后的child将获得更新后的值。 -
当我将完成的道具传递给子组件时,是的,它会更新道具以及子组件中“完成”的数据。但是,当我尝试 checkall 时,父组件中的道具发生了变化,但它并没有改变子组件中“完成”的数据。
标签: vue.js