vue.js - 在这种情况下,组织 Vue.js 组件之间通信的最佳方式是什么?
问题描述
我有一个数组
[
{
"id": 0,
"title": "Task #1",
"description": "Task description",
"solutions": [
{
"solutionId": 0,
"text": "First solution text",
"isMarked": true
},
{
"solutionId": 1,
"text": "Second solution text",
"isMarked": false
}
]
},
{
"id": 1,
"title": "Task #2",
"description": "Task description",
"solutions": [
{
"solutionId": 0,
"text": "First solution text",
"isMarked": true
},
{
"solutionId": 1,
"text": "Second solution text",
"isMarked": true
},
{
"solutionId": 2,
"text": "Third solution text",
"isMarked": true
}
]
}
]
它表示任务和解决方案变体的列表。
我需要一个机会来切换isMarked
解决方案的价值,true/false
只需点击它。
我创建了一个这样的组件结构:
// index.vue
<template>
<div class="task-list">
<Task v-for="task in tasks" :key="task.id" :task="task" />
</div>
</template>
<script>
// ...
data() {
return {
tasks: [/* the array of tasks */]
}
}
</script>
// task.vue
<template>
<div>
<h1>{{ task.title }}</h1>
<p>{{ task.description }}</p>
<SolutionsList :solutions="task.solutions" />
</div>
</template>
// ...
// solutionsList.vue
<template>
<div>
<Solution v-for="solution in solutions" :key="solution.id" :solution="solution" />
</div>
</template>
// ...
// solution.vue
<template>
<div>
<p>{{ solution.text }}</p>
<span @click="toggleMark">{{ markLabel }}</span>
</div>
</template>
<script>
// ...
computed: {
markLabel() {
return solution.isMarked ? 'Unmark' : 'Mark'
}
},
methods: {
toggleMark() {
// ???
}
}
</script>
例如,我可以将此状态存储在 Vuex 中,而data()
不是index.vue
. 而且我需要进行 API 调用以更改 isMarked
单击的任务解决方案的值。
问题来了:最好的方法是什么?如果solutionId
是唯一的最后手段,我可以遍历 Vuex 中的所有任务以找到它solutionId
并在那里更改状态。但在这种情况下solutionId
,并不是所有任务都是唯一的。
我看到了哪些解决方案:
使用单独的道具将任务传递
id
给每个人。但是在这种情况下,如果组件是深度嵌套的并且它可以是深度嵌套Solution
的,我需要为每个组件创建很多道具。Solution
最好只
toggleMark
从组件发出事件Solution
并在组件中捕获它,Task
但在我的深度嵌套Solution
组件的情况下,我需要在每个父组件中重新发出它以Task
.我可以在
Solution
组件中调用 Vuex 操作来 mutateisMarked
。但是我仍然需要一个任务id
来找到一个包含这个点击解决方案的父任务。我可以使用事件总线,但它在现代方法中并不受欢迎。
例如,我可以创建另一个计算方法并将每个方法与它们的父任务
index.vue
映射以创建一个新字段并传递结果对象而不是. 但它看起来有点脏。solution
id
taskId
tasks
我
provide / inject
至少可以使用。对于这种情况,这将是一个很好的解决方案。但是如果Solution
不是 a 的子组件,Task
它会在随机位置。
这只是一个轻量级的问题示例。当然,只要扔掉SolutionsList
并发出toggleMark
事件就完美了,但是组件的中间组件Solution
可能很多,或者它可能不是组件的子Task
组件。
请告诉我如何以最好的方式解决这个问题?