我们来探讨前端组件方面的问题,假设有这么一个需求:
1、我有一个任务管理页面: task-mangerment.vue
2、然后这个页面中有一个 task-list.vue 组件, 用于展示任务列表,同时还有一些其他的交互
3、 task-list.vue 组件的每一项是一个 task-item 组件
4、我通过一个 store 来维护 tasks,task可能需要显示在其他的页面上,比如 index.vue 里面
现在有一个问题,我要对任务进行管理的话,如做 增加,删除,修改 操作时,我事件触发的起点是 task-item ,点击或者长按某个 task-item ;
我应该在task-item内部就将这些事情搞定了,还是说,task-item 将事件emit 出来,交给上层task-list.vue 来处理呢?
我分别给出两种代码实现:
task-item.vue
<template>
<div>
<span>{{ task.name }}</span>
<button @click="deleteTask">删除</button>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
props: {
task: {
type: Object,
required: true
}
},
methods: {
...mapActions(['deleteTask'])
}
}
</script>
task-list.vue:
<template>
<div>
<task-item
v-for="task in tasks"
:key="task.id"
:task="task"
></task-item>
</div>
</template>
<script>
import TaskItem from './task-item.vue';
export default {
components: {
TaskItem
},
computed: {
tasks() {
return this.$store.state.tasks;
}
}
}
</script>
task-item.vue:
<template>
<div>
<span>{{ task.name }}</span>
<button @click="emitDelete">删除</button>
</div>
</template>
<script>
export default {
props: {
task: {
type: Object,
required: true
}
},
methods: {
emitDelete() {
this.$emit('delete-task', this.task.id);
}
}
}
</script>
task-list.vue:
<template>
<div>
<task-item
v-for="task in tasks"
:key="task.id"
:task="task"
@delete-task="deleteTask"
></task-item>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import TaskItem from './task-item.vue';
export default {
components: {
TaskItem
},
computed: {
tasks() {
return this.$store.state.tasks;
}
},
methods: {
...mapActions(['deleteTask'])
}
}
</script>
相信很多做组件化的同学都遇到过这种类似的问题,那么究竟那种方式更加可取呢?就是今天这篇文章的主题了。
在这种情况下,我建议将事件处理放在上层组件(task-list.vue)中,并使用 emit 将事件从 task-item.vue 组件传递到上层组件。这样做的好处有以下几点:
可能上面的方案,有很多人还是会觉得不服,说,我放在task-item里面怎么就不解耦了,也很高内聚呀,task-list的逻辑也很清晰呢?
这种说法也不能说完全不对,把所有的增删改操作放在 task-item 里面确实是可行的,但这样做可能会导致一些问题:
1. 职责不清晰:将所有的增删改操作都放在 task-item 组件中,会使得这个组件变得复杂,职责不明确。按照组件化的设计原则,每个组件应该只关注自己的职责,降低组件间的耦合度。task-item 组件的主要职责应该是展示任务项,而不是处理任务的增删改操作,你分别站在task-list的立场和task-item的立场来看看,谁更加适合做这个任务的管理角色。
2. 难以复用:如果将所有操作都放在 task-item 组件中,当你需要在其他地方使用类似的任务项组件时,可能需要重新编写一个新的组件,或者对现有组件进行修改。而将事件抛出到外层,使得 task-item 组件更加独立,可以在其他地方直接复用,越是底层的组件,就越应该职责单一,能不干的就不干,干了就麻烦大了,一旦遇到其他组件引用你,但是不需要你的一些功能时,你就得改。
3. 数据管理困难:如果将所有操作都放在 task-item 组件中,那么每个 task-item 都需要与 Vuex 进行交互,这会导致数据管理变得复杂。将事件抛出到外层,统一由 task-list 组件处理,可以更好地利用 Vuex 的功能,使得数据管理更加清晰。
在Vue 的组件化思想中,将一个复杂的应用程序分解为多个独立、可复用的组件,每个组件只关注自己的职责,降低组件间的耦合度。这种设计思想有助于提高代码的可维护性和可读性。将事件抛出到外层的原因也是为了遵循 Vue 的组件化思想,使得每个组件的职责更加明确。
因此,通过以上的分析,在这个例子中,task-item 组件的职责是展示任务项,而 task-list 组件的职责是管理任务列表。将事件抛出到外层,可以使得 task-item 组件更加独立,便于复用和维护。同时,将事件处理放在上层组件中,可以更好地利用 store 的功能,使得数据管理更加清晰。不知道你理解了没有,欢迎一起交流把,没有任何一种说法永远都是对的,连牛顿第一定律这种公理性的也只能放在宏观力学上才好使,更别提我说表达的观点,因此多思考,那种符合自己的项目,什么方式在大多数场景下是凑效的,而不是跟风。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。