请教一个前端写组件拆分的问题

259 天前
redbeanzzZ  redbeanzzZ
用 vue 写前端业务时候,我经常会遇到什么内容需要提出来写组件的问题。如果业务中这个组件比较复杂,复用性高,我肯定会把他拿出来写个组件复用。
我现在有一个场景想问下大家会怎么写:一个列表页有多个按钮,都是展开一个抽屉进行表单填写的,一共有七八个按钮。我把抽屉的框架拿出来写个组件(比如标题,确认框这样),内部的表单内容再根据业务不同单个文件引入。同事认为这七八个表单有两三个还有相似的地方,还是可以复用,还要继续把相似的表单继续拿出来写个组件用。

我觉得那七八个页面已经很简单,我直接写逻辑会更清晰一些。这种情况哪种才是对的呢?
1077 次点击
所在节点   问与答  问与答
21 条回复
ljsh093
ljsh093
259 天前
领导要求看着做,不是领导要求的那谁提谁干呗
zcf0508
zcf0508
259 天前
不要过度抽象
shilianmlxg
shilianmlxg
259 天前
抽离的话,最好先问问自己:
1. 是否有逻辑上共用并且依赖 UI 交互,比如需要弹出框的确认和关闭按钮,都会有异步关闭。单把这个 dialog 封装成一个组件。
2. 这个逻辑共用但不依赖 UI 交互,可以抽成 hooks
3.是否可以把内部业务,拆成 slot 。
你这个可以写个公用 wrap 组件,然后里面再 slot 插槽不同的业务组件。个人的愚见,这样是我能想到的最好了。蹲下其他大佬的最优解。
ruoxie
ruoxie
259 天前
不要过度抽象
MrLeo
MrLeo
259 天前
不要过度抽象
66beta
66beta
259 天前
表单在拆分,那就是通用组件了呗,比如:国家选择器、货币选择器

不知道你说的"还可以复用",是指什么
Xu3Xan89YsA7oP64
Xu3Xan89YsA7oP64
259 天前
除非你说的『相似』是指类似于新增与更新这种填写内容几乎没差别的,否则没必要。
Adyi
Adyi
259 天前
参考 elementUI
vczyh
vczyh
259 天前
简单表单没必要复用,除非 FormItem 比较复杂,比如是个从接口获取的 Select List 这样才有必要复用。
Jarme
Jarme
259 天前
不要过度抽象、业务剥离、纯粹性、易用(心智负担)
redbeanzzZ
redbeanzzZ
259 天前
@shilianmlxg 我实际业务中,这个抽屉就是一个 header content footer 的结构。header 和 footer 完全一样,我拿出来携程组件了。每个按钮对应抽屉的 content 是一个表单,他们不一样,这里我把每个 content 单独拿出来写成组件。其中会有两个表单中 content 内容是一样的,但是校验不同、个别项为 disabled 无法编辑这样。
redbeanzzZ
redbeanzzZ
259 天前
@66beta 就是两个表单,比如有三个 item ,对应国家选择器、货币选择器、时间选择器,但是两个表单的校验规则不同,还有其中一个时间选择器可能是 disabled 无法选择这样。
redbeanzzZ
redbeanzzZ
259 天前
https://i2.mjj.rip/2024/06/07/18bc9ff508d25a5ac112a0d7cfd78953.png 我直接把图放出来咯,我已经把外面那个抽屉框子封好组件了。这俩表单虽然一样,但是否可编辑不同,校验规则不同,内容又这么少我还不如直接写吧?以后新需求基本也不可能再有一样表单。
@zcf0508
@shilianmlxg
@66beta
@shizhibuyu2023
@vczyh
shilianmlxg
shilianmlxg
259 天前
@redbeanzzZ #12 你可以看下动态表单 form 低代码的文档,看下人家是抽离的什么,相信你现在再看会有些灵感。https://www.form-create.com/v3/instance#%E7%BB%84%E4%BB%B6%E6%96%B9%E6%B3%95
redbeanzzZ
redbeanzzZ
259 天前
@shilianmlxg 好的!谢谢
Charrlles
Charrlles
259 天前
不是说长的像就要抽象的,这种和业务相关的组件开发说了不算,得拉通产品和设计,讨论清楚到底会有几种场景几种样式,然后制定组件规范才行,不然后面产品提一个组件满足不了的需求,就傻眼了
redbeanzzZ
redbeanzzZ
259 天前
@Charrlles 我知道你说的意思,我说的不是产品的那些大的组件,而是自己开发时候方便自己使用封装的组件
lDqe4OE6iOEUQNM7
lDqe4OE6iOEUQNM7
258 天前
<!-- DrawerForm.vue -->
<template>
<el-drawer :visible.sync="visible" title="Form Drawer">
<header>
<slot name="header"></slot>
</header>
<div>
<slot></slot>
</div>
<footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</footer>
</el-drawer>
</template>

<script>
export default {
props: {
visible: Boolean
},
methods: {
handleSubmit() {
this.$emit('submit');
}
}
};
</script>
lDqe4OE6iOEUQNM7
258 天前
<!-- CommonFormFields.vue -->
<template>
<el-form :model="formData" :rules="rules" ref="form">
<el-form-item label="整改部门" prop="department">
<el-select v-model="formData.department" :disabled="isDepartmentDisabled">
<!-- Options -->
</el-select>
</el-form-item>
<el-form-item label="整改人" prop="person">
<el-select v-model="formData.person">
<!-- Options -->
</el-select>
</el-form-item>
<el-form-item label="计划完成时间" prop="date">
<el-date-picker v-model="formData.date" :disabled="isDateDisabled">
</el-date-picker>
</el-form-item>
</el-form>
</template>

<script>
export default {
props: {
formData: Object,
rules: Object,
isDepartmentDisabled: Boolean,
isDateDisabled: Boolean
},
methods: {
validate(callback) {
this.$refs.form.validate(callback);
}
}
};
</script>
lDqe4OE6iOEUQNM7
258 天前
具体业务:<!-- SomePage.vue -->
<template>
<div>
<el-button @click="showDrawer1 = true">Open Drawer 1</el-button>
<el-button @click="showDrawer2 = true">Open Drawer 2</el-button>

<DrawerForm :visible.sync="showDrawer1" @submit="handleFormSubmit1">
<template #header>
认领
</template>
<CommonFormFields
:formData="formData1"
:rules="rules1"
:isDepartmentDisabled="true"
:isDateDisabled="false" />
</DrawerForm>

<DrawerForm :visible.sync="showDrawer2" @submit="handleFormSubmit2">
<template #header>
指派
</template>
<CommonFormFields
:formData="formData2"
:rules="rules2"
:isDepartmentDisabled="false"
:isDateDisabled="false" />
</DrawerForm>
</div>
</template>

<script>
import DrawerForm from './DrawerForm.vue';
import CommonFormFields from './CommonFormFields.vue';

export default {
components: {
DrawerForm,
CommonFormFields
},
data() {
return {
showDrawer1: false,
showDrawer2: false,
formData1: {
department: '',
person: '',
date: ''
},
formData2: {
department: '',
person: '',
date: ''
},
rules1: {
department: [{ required: true, message: '请选择部门', trigger: 'change' }],
person: [{ required: true, message: '请选择认领人', trigger: 'change' }],
date: [{ required: true, message: '请选择日期', trigger: 'change' }]
},
rules2: {
department: [{ required: true, message: '请选择部门', trigger: 'change' }],
person: [{ required: true, message: '请选择指派人', trigger: 'change' }],
date: [{ required: true, message: '请选择日期', trigger: 'change' }]
}
};
},
methods: {
handleFormSubmit1() {
this.$refs.form1.validate((valid) => {
if (valid) {
// 提交逻辑
}
});
},
handleFormSubmit2() {
this.$refs.form2.validate((valid) => {
if (valid) {
// 提交逻辑
}
});
}
}
};
</script>

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1047730

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX