> @author: 郭瑞峰 > @createTime: 2023/04/17 > @updateTime: 2023/05/04 ### 前言 之前与外企的伙计交流感情后得知他们的前端开发思路,于是乎便深入了解了这一套开发,深受震撼,写一篇文章记录记录 ( ̄︶ ̄)↗ # 概念 ~~不听不听王八念经~~ * atoms 原子层 * 只有数据展示和样式,**最好不能涉及代码逻辑** * molecules 分子层 * 导入并组合atoms(原子),会涉及部分样式调整(比如说间距,位置),会涉及代码逻辑(比如数据绑定,原子间的相互交互逻辑,应用层给的数据处理) * organism 应用层(注:直译是“有机体”) * 导入bing组合molecules(分子),建议只涉及接口请求(只是建议,毕竟分子层优先满足公用,不能满足一些应用层特殊情况) * hooks 逻辑层(vue2能把函数封装成公共函数就用吧) * 将常用的逻辑封装成公共函数,写入这里面,需要调用就导入调用 # 示例 之前写的一团糟,故写了个demo方便理解(`vue2`的写法) demo地址:[article14](https://github.com/telescope114/article14 "article14") 国内镜像:[gitee地址](https://gitee.com/Xiaoxiaoxuan11/article14) ## table的二次封装 ##### 第零步,组件写在哪儿 别笑,我是认真的 (~ ̄(OO) ̄)ブ 分析:组件涉及**展示**和**操作**,还涉及很多其他组件相互配合(如进度条,标签),所以说放在`molecules`分子层 ##### 第一步,确定数据来源 ```html ...... ``` 这里可以看见部分要用的`table`组件的参数,这里我们要做第一步分析,分析它的数据是 **从父组件获取** 还是 **直接配置**,这里我就直接分析了 * 父组件获取:列配置`columns`、列数据`dataSource`、加载状态`loading` * 直接配置:key取值`rowKey`、边框`bordered`、分页设置`pagination` 当然,还有其他可配置项,如 滚动`scroll`、表标题`title`、部分自定义功能如选择框,反选`rowSelection`等 ##### 第二步,简化数据输入 确定完父元素所有传入值后,对每一个值进行分析 * 列配置`columns`:大部分配置的值和key值绑定,故**可以简化** * 列数据`dataSource`:数据来源于后端JSON/JSONP,无法判断内容,故**不可简化** * 加载状态`loading`:~~大佬,这个能简化么(╬▔皿▔)╯~~ 对columns进行简化: ```ts // ./src/components/organisms/PageTable.vue:20 const columns: myTableColumns = [ { key: 'name', value: '名称', type: 'string' }, { key: 'status', value: '状态', type: 'badge' }, { key: 'dateTime', value: '时间', type: 'dateTime' }, { key: 'progress', value: '进度条', type: 'progress' }, { key: 'others', value: '操作', type: 'others' } ] ``` `myTableColumns`类型 ```typescript // ./src/components/types/myTable.ts:3 export type myTableColumn = { // 关键词, 如'name'之类的 key: string // 展示文本, 如'名称'之类 value: string // 展示类型,这里可以用枚举限制, 如展示'进度条'、'标签'、'徽标' type: string // 根据业务需要,请自己添加其他东西 // width?: number } export type myTableColumns = myTableColumn[] ``` ##### 第三步,补全简化数据 将上述的`columns`代码补全成`ant-design-vue`能识别的类型 ```typescript // ./src/components/molecules/MyTable.vue:53 computed: { tableColumns (vm: { columns: columns }) { // vm = this return vm.columns.map(setColumn) } } ``` 因为列配置的细节有些许多,故我将列配置的细节单独导出成hooks ```typescript import { myTableColumn, antTableColumn } from '../types/myTable' import { h } from 'vue' import MyProgress from '../atoms/MyProgress.vue' import MyBadge from '../atoms/MyBadge.vue' import MyTime from '../atoms/MyTime.vue' /** 将外层配置的列选项转化成 ant-table 能识别的column * * @param item: {myTableColumn} */ export const setColumn = (item: myTableColumn): antTableColumn => { const out: antTableColumn = { title: item.value, dataIndex: item.key, key: item.key, ellipsis: true } if (item.type === 'others') { out.scopedSlots = { customRender: item.key } } else { out.customRender = (text) => { // 对 type进行处理,这里做示例 switch (item.type) { case 'progress': return h(MyProgress, { props: { data: text, color: '#18e87f' }, domProps: {} }) case 'badge': let color = '' // eslint-disable-line no-case-declarations let str = '' // eslint-disable-line no-case-declarations switch (text.toString()) { case '1': color = '#2db7f5' str = '正常' break case '2': color = '#fadb14' str = '下线' break case '3': color = '#f5222d' str = '错误' break default: color = '#414141' str = '未知' } return h(MyBadge, { props: { data: str, color: color }, domProps: {} }) case 'dateTime': return h(MyTime, { props: { time: text } }) default: return text || '--' } } } return out } export default {} ``` * 这里说一下,列表展示中会有按钮操作,如编辑、启/禁用等,所以说一定要设置`others`处理 * 里面涉及了一些其他的没见过的以`My`开头的组件,下一个涉及的部分 ##### 第四步,封装特殊组件 我这里是封装了 进度条,徽标数,时间显示(这个可以用hooks代替的) ```html ``` * props直接写数组就行,降低代码量 * 若是不得不涉及变量计算的,统一使用computed处理 * **封装后统一写在`atoms`内部** ## description的二次封装 ##### ~~第零步~~ ~~别想了,写在 molecules 里面~~ ##### 第一步,数据来龙去脉 ```html ``` 这里就直接上分析了 * 父组件获取:标题`title`、列数量`columns` * 直接配置:尺寸`size`、边框`border` * 其他可配项:布局`layout` 聪明的你一定发现了,这个数据怎么展示呢? `description`有它的儿子`description-item`,咱对它儿子进行循环就行了(总感觉怪怪的),循环数组一定得从父组件内获取,再根据父组件传入的展示对象展示即可 ```html ``` ```ts props: { value: { type: Object, default: () => ({}) }, config: { type: Array, default: () => ([]) }, title: { type: String, default: () => '基本信息' }, column: { type: Number, default: () => 4 } } ``` ##### 第二步,规范传入类型 直接上父组件吧,方便理解 ```html ``` 这里我偷懒了,应该设置config输入的数据类型 = ̄ω ̄= ##### 第三步,分析调用原子 直接上源码 ```html ``` 按照原型图、UI设计图调用封装的atoms组件,完成数据展示 # 后话 我写的demo层级结构是这样的 ``` components atoms [MyBadge.vue, MyLevel, MyProgress, MyTime] hooks [myTable] molecules [MyDescription, MyTable] organisms [DescriptionShow, PageTable] types(忽略了) ``` 个人使用感觉: * 优势 * 传入就用,节约代码开发成本 * 层级少,封装就调用 * 需求更改时只修改配置代码 * 劣势 * 业务不清晰时会频繁修改封装内容 * 提升了新人学习成本 * 提前规划好管理atoms层组件名称、作用、注释 * 需要定期熟悉atoms层内组件 最后修改:2023 年 05 月 04 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏