【发布时间】:2017-10-26 01:31:45
【问题描述】:
我正在使用 Vue 2.0 使用内置的父子通信构建一个简单的待办事项应用程序。直接附加到Vue实例的父元素(new Vue({...})如下:
<!-- Tasks.vue -->
<template>
<div>
<create-task-form></create-task-form>
<task-list :tasks="tasks"></task-list>
<task-list :tasks="incompleteTasks"></task-list>
<task-list :tasks="completeTasks"></task-list>
</template>
<script>
import CreateTaskForm from './CreateTaskForm.vue';
import TaskList from './TaskList.vue';
export default {
components: { CreateTaskForm, TaskList },
data() { return { tasks: [] }; },
created() { // Ajax call happens here...
axios.get('/api/v1/tasks')
.then(response => {
this.tasks = response.data;
console.log(this.tasks); // THIS IS LOGGED LAST
});
},
computed: {
completeTasks() {
return this.tasks.filter(task => task.complete);
},
incompleteTasks() {
return this.tasks.filter(task => task.complete);
}
}
}
</script>
这个想法是<tasks></tasks> 将显示一个用于创建新任务的表单,以及 3 个列表 - 所有任务、未完成任务和完成任务。每个列表都是相同的组件:
<!-- TaskList.vue -->
<template>
<ul>
<li v-for="task in taskList">
<input type="checkbox" v-model="task.complete"> {{ task.name }}
</li>
</ul>
</template>
<script>
export default {
data() { return { taskList: [] }; },
props: ['tasks'],
mounted() {
this.taskList = this.tasks;
console.log(this.tasks); // THIS IS LOGGED FIRST
}
}
</script>
问题
如您所见,我正在尝试使用动态 :tasks 属性将数据从 <tasks> 传递到 3 个 <task-lists> 中的每一个:
<task-list :tasks="tasks"></task-list>
<task-list :tasks="incompleteTasks"></task-list>
<task-list :tasks="completeTasks"></task-list>
注意,我没有使用共享(全局)状态,因为每个列表都需要不同部分数据,即使这些部分数据属于同一个存储.但问题是:tasks 被分配了一个空数组在 Ajax 调用发生之前;正如我猜测的那样,道具是不可变的,因此当在父<tasks> 中获取数据时,子<task-list> 中的tasks 永远不会更新。事实上,<task-list> 是首先创建的(请参阅日志),然后只有在此之后才能使用 Ajax 获取数据。
问题
- 如何将数据从
<tasks>传递到我的<task-list>s?如何确保所有组件都引用动态更新的单一事实来源? - 有没有办法用“vanilla”Vue.js 解决这个父子通信问题?还是我需要使用 Vuex 或类似的东西?
- 我是否正确使用属性将数据传递给孩子?还是应该在全局变量中使用共享存储?
【问题讨论】:
-
使用共享全局存储不是这里的问题。正如@wostex 所回答的,mounted() 只被调用一次。因此,要更新 taskList 属性,您应该使用计算属性。如果您考虑使用全局存储 vuex 将最好地解决您的目的。您可以在此处找到与您相关的示例(coligo.io/learn-vuex-by-building-notes-app)
-
@user7814783 我在全局存储中遇到的问题(我的意思是global var declared right before the parent
<tasks>组件)是每个子<task-list>组件都需要它自己的数据版本(所有、不完整和完整的任务)。但它仍然是相同的组件! (<task-list>) 所以我不知道如何从同一个商店传递不同部分的数据。
标签: vue.js vuejs2 vue-component