新版代练服务功能的设计
前言
目前,项目已有代练功能模块,但随着业务发展,现有功能已无法满足需求。因此,我们需要对其进行优化,以提升功能的灵活性与可维护性。
此次更改基于上一版设计进行改进。
问题分析
原有的代练功能通过渲染组件列表实现,不同类型的组件(如按钮、下拉框、输入框等)根据类型进行渲染。但该设计存在以下问题:
- 组件耦合严重:组件内嵌多个子选项,且子选项类型固定,无法扩展。例如,按钮组的子选项只能是按钮。
- 组件类型固定,无法组合扩展:无法自定义或组合不同组件类型。
- 组件关联复杂难维护:组件间联动依赖条件数组,复杂逻辑导致数组膨胀,难以维护。
- 文案编辑不便:文案样式硬编码,需复制竞品文案并覆盖样式,导致维护困难。
优化目标
针对上述问题,优化后的设计目标如下:
- 组件原子化:拆分为更细粒度的原子组件。
- 组件可扩展、可组合:支持自定义组合组件。
- 灵活的组件关联机制:简化组件联动逻辑。
- 便捷的文案编辑:引入富文本编辑器,支持自定义插件。
思路
整体设计思路
- 原子化组件:将所有组件拆分为最小功能单元,确保每个组件单一职责,以便灵活组合和扩展。
- 可组合架构:通过容器组件实现原子组件的组合,使复杂界面结构可以通过简单的组件堆叠构建。
- 数据驱动渲染:所有组件均通过配置数据进行渲染,确保界面的灵活性和可配置性。
- 事件驱动交互:使用事件监听和派发机制处理组件间的交互与关联,减少硬编码逻辑。
- 低耦合高内聚:各组件之间通过标准接口交互,降低耦合度,增强可维护性。
局部设计思路
- 组件关联逻辑:采用
Token
机制,将组件间的关联逻辑可视化,运营人员可以通过拖拽组合实现复杂交互。 - 表单数据监听:使用原生事件监听
form
的change
和input
事件,以保证所有交互数据能被准确捕获,并使用防抖优化性能。 - 文案编辑功能:引入富文本编辑器并支持插件扩展,确保文案的灵活性和可定制性。
- 价格与时间计算逻辑:组件支持动态价格和时间计算,通过配置规则和条件实现自定义计算逻辑。
- 折扣逻辑设计:折扣通过
DiscountConfig
和DiscountItem
数据结构定义,支持多层折扣叠加和条件限制。
功能调整
组件原子化
将原有的复合型组件拆分为更基础的原子组件。例如:
- 从按钮组中独立出单个按钮组件。
- 从下拉框中拆分出下拉选项。
- 新增基础组件,如标题、文本、提示等。
组件关联机制优化
原有的条件数组机制保留,但改进为基于原子化 Token
的关联逻辑。预定义的
Token
(如【选中】、【组件】、【隐藏】等)可以被运营人员拖动拼接,形成逻辑链条。
例如:
- 逻辑示例:如果【组件】【选中】,则【组件】【隐藏】。
文案编辑优化
- 引入 富文本编辑器 支持灵活的文案编辑。
- 通过自定义插件满足特殊样式需求。
数据结构设计
定义代练功能的数据结构,以支持灵活的组件管理与交互。
declare type ComponentID = number
declare type ContainerType = 'container'
declare type ComponentType =
| ContainerType
| 'title'
| 'text'
| 'tip'
| 'button'
| 'slider'
| 'double-slider'
| 'input'
| 'help'
| 'select'
| 'radio'
| 'checkbox'
| 'link'
| 'icon'
declare type Component<V = unknown> = {
id: ComponentID
type: ComponentType
label?: string
name?: string
value?: V
group: string | number
time?: number | `${number}%`
price: number | `${number}%`
text?: string
checked?: boolean
show?: boolean
order?: number
min?: number
max?: number
step?: number
point?: Array<{
value: number
price: number
time: number
}>
pattern?: 'string' | 'number'
}
declare type Condition = {
id: number
condition: string
action: string
}
declare type DiscountConfig = {
value: number
type: 'percent' | 'value'
append: number
minPrice: number
maxPrice: number
minQuantity: number
maxQuantity: number
limit: number
name: string
description: string
startTime?: number
endTime?: number
enabled: boolean
}
declare type DiscountItem = {
quantity: number
price: number
discount: number
progress: number
}
实现方案
组件架构
将代练功能拆分为以下组件层级:
详情页
└ 选项面板
└ 选项容器
└ 选项包装器
└ 选项组件
详情页
- 渲染基础页面结构,如导航栏、页面文案。
- 管理数据获取与更新逻辑,统一处理数据流。
- 使用单向数据流(props)传递数据。
- 通过
form
标签包裹选项,监听change
和input
事件,收集表单数据。
选项面板
- 使用
form
组件包裹选项,控制折扣、图片和加购按钮的展示。 - 渲染传入的选项数据,基于“容器为行,组件为列”进行排布。
选项容器
- 对组件进行分类渲染,控制当前行的排列。
- 负责组件传递,不参与数据处理。
选项包装器
- 对组件进行统一包装(如添加 props、dataset 等)。
- 方便在统一位置修改所有组件的通用逻辑。
选项组件
- 渲染具体的交互组件(如按钮、滑块、下拉框等)。
- 仅负责展示和基本交互,不直接处理数据更新。
逻辑实现
表单数据监听与更新
- 使用原生
addEventListener
监听form
的change
和input
事件。 - 避免使用 React 合成事件,以确保手动触发的事件也能被捕获。
- 采用防抖(debounce)策略优化性能,防止频繁触发事件。
组件关联逻辑
- 通过
Token
实现灵活的组件关联。 - 检查条件并更新关联状态,避免数据冲突(如滑块范围重叠)。
总结
本次设计通过以下改进,显著提升了代练功能的灵活性和可维护性:
- 组件原子化:提升了组件的扩展性与组合性。
- 灵活的关联机制:简化了复杂逻辑的实现。
- 便捷的文案编辑:增强了文案自定义能力。
- 清晰的数据流:统一的数据管理减少了耦合度,提升了代码质量。
新版代练服务功能的设计
http://www.inksha.com/archives/xin-ban-dai-lian-fu-wu-gong-neng-de-she-ji