在团队里待久了,你一定能遇见这种画面:策划在需求文档里写“点击按钮,弹出礼包页,首次进入还要显示红点提醒”,然后需求落到程序员手上,排期、开发、测试、上线。等活动上线了,运营说“曝光埋点换一个字段”,策划又说“红点改成只有VIP用户才显示”,于是一轮新需求又开始了。我负责过一个活动系统,单是“按钮弹窗”这一个事件,一个月改了七版,程序员大半时间都耗在重复又琐碎的交互逻辑上。当时我就动了念头:能不能让策划不写代码也把事件配出来?不是教策划学编程,而是把程序员脑子里的“事件”翻译成可视化的配置项。今天这篇就把这套思路、踩过的坑和最终协作方式完整摊开说。
这个思路听起来像是低代码,但又不完全是。低代码平台往往面向专业开发者,我希望做的是让完全不懂代码的策划和设计师,也能在一个面板上组合出复杂交互。项目上线后,有个策划跟我说:“这比我用PPT画交互稿爽多了。”那一刻我觉得方向对了。下面从需求拆解开始。
1. 先搞清楚:程序员嘴里的“事件”,策划怎么理解
1.1 同样说“点击”,两个人脑子里是两个东西
程序员的“点击”不是一个动作,而是一串状态:浏览器捕获了鼠标按下、弹起,生成了一个click事件对象,里面带着坐标、target、currentTarget,还要考虑冒泡、委托、默认行为。策划口中的“点击”就是一句话:用户按了这个地方,东西要弹出来。
所以配置系统的第一件事,不是让策划理解什么叫addEventListener,而是把这两个世界接起来。我见过很多失败的低代码尝试,是因为把技术名词直接搬进界面,比如条件选择器里出现“全等”、“严格等于”、“事件对象属性”,策划看到就懵了。好的做法是把“事件”翻译成产品语言:谁触发、什么条件、做什么、完事有什么反馈。这也是整个配置系统四个核心字段的来源。
1.2 把事件拆成四块:谁触发、什么条件、做什么、反馈
我落地时把一次完整交互拆成四段,策划只需要按顺序选:
| 维度 | 含义 | 例子 |
|---|---|---|
| 触发源 | 哪个组件、哪种操作 | 首页Banner、点击/双击/长按/滑到可视区 |
| 条件 | 满足什么才执行 | 用户等级大于3、今天没弹过、广告开关打开 |
| 动作 | 执行什么反馈 | 弹窗、跳转、显示Toast、发埋点、调接口 |
| 副作用 | 动作完成后额外处理 | 关闭弹窗、刷新列表、上报曝光 |
在界面上,这四段就是一个大表单。策划不用写if,不用写function,只需要在触发源下拉框里选“首页Banner”,在动作里选“弹出礼包页”,再填一个“礼包ID”参数。运行时的解释器拿到这段配置数据,自动完成事件绑定、条件判断和动作调用。这个模型后来被团队当成模板,许多低频活动只要一小时就能上线,而以前至少要排三天开发。
1.3 委托和事件机制,恰好是配置系统的地基
有编程经验的读者一定熟悉“委托和事件”:不是给每个按钮都写死逻辑,而是定义一个事件源,让不同的行为去订阅。可视化配置系统做的正是这件事——策划在面板上每配一条规则,本质就是订阅了一次“事件源 + 条件 + 动作”。底层运行时代码只有一套,但配置可以无限变。
第一版我把配置数据存成JSON,类似这样:
json复制{
"id": "event_20240115_001",
"name": "首页Banner点击弹礼包",
"trigger": {
"source": "home_banner",
"type": "click"
},
"condition": {
"logical": "and",
"items": [
{ "field": "user.level", "operator": "gt", "value": 3 },
{ "field": "today.popup_count", "operator": "eq", "value": 0 }
]
},
"actions": [
{ "type": "show_popup", "params": { "popup_id": "gift_202" } },
{ "type": "track", "params": { "event_name": "banner_click" } }
]
}
策划不感知这个JSON,但程序员在控制台能一眼看出问题。这个数据结构的最大好处是:配置可以保存、可以回滚、可以做AB实验。以前“改按钮跳转地址”都要发版本,现在运营在后台改一个参数就完事。反过来,如果一开始就让策划提交一段JS片段,那配置系统就失去意义了——那是换了一种方式写代码,并不是真正解决协作问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 配置系统怎么设计才不翻车
2.1 核心模型:事件源、触发器、条件、动作
设计配置系统时,最先要定的是数据模型。我最终确定的模型是:事件源(EventSource)、触发器(Trigger)、条件(Condition)、动作(Action)。事件源是“谁身上可以绑事件”,它可以是页面全局,可以是某个组件,也可以是自定义组件暴露出来的逻辑单元。
触发器要区分用户型和系统型。用户型包括点击、双击、长按、触摸移动、输入变更;系统型包括页面加载完成、接口返回后、进入可视区、离开页面、定时器触发。很多团队只做了点击,结果策划想配“滚动到某个模块时自动上报曝光”,就只能再提需求。我建议在第一版就把常见的用户型和系统型触发器都列进去,哪怕一开始动作少一些,触发器的覆盖度决定了系统的上限。
条件模块要支持组合。最稳妥的做法是条件组:多个条件之间支持“并且”和“或者”,另外还要支持“不满足”(非)。例如“用户等级大于3 并且 今天未弹过窗”。条件字段的来源要从公共数据字典里选,不能随手写死在配置里。比如“用户等级”“今日登录次数”这些字段由程序预埋,策划只能在下拉里选。这样做既限制了策划写出技术无关的字段错误,也方便运行时统一取值。
动作模块建议做成可扩展的“动作插件”机制。系统内置弹窗、跳转、埋点、Toast、请求接口、修改组件样式/文案/显隐等常用动作;如果业务需要新的动作类型,由程序员按照动作接口规范开发一个插件,然后在配置面板里就会自动出现新动作。这样策划依然不写代码,但可用范围会因为业务沉淀而不断变大,而不是永远固定。
2.2 条件判断可视化,别让策划填代码
最容易翻车的界面是条件编辑器。我见过一个后台把条件表达式写成一个文本框,让策划输入user.level > 3 && popupCount === 0,这叫“不写代码”吗?表面是省了前端开发,实际上把语法负担全甩给了用户。
正确姿势是做成一行一行的自然选择。例如配置“用户等级大于3”,界面上就是三个控件连起来:字段下拉框选“用户等级”、操作符下拉框选“大于”、数值输入框填“3”。操作符选项也要面向产品:大于、小于、等于、不等于、包含、不包含、为空、不为空,少放“全等、半等、正则匹配”这类程序员概念。
需要复杂组合时,用条件组嵌套。在界面上表现为一个“添加条件组”按钮,每个条件组内部有“并且/或者”切换,组与组之间也可以设置关系。展开后大概像:
- 条件组A(并且)
- 用户等级 大于 3
- 今日弹窗次数 等于 0
- 或者
- 条件组B(并且)
- 用户标签 包含 “核心用户”
- 活动开关 等于 开启
这样策划只需要理解“并且/或者”,不至于把逻辑搞成一团。为了校验逻辑正确,我在配置面板旁边放了一个“逻辑预览”区块,实时把这个条件翻译成一句中文描述,比如“当用户等级大于3,并且今日弹窗次数等于0时,满足条件”。策划看完基本都能确认自己配得对不对。
2.3 自定义组件绑定原生事件:给设计器留钩子
很多组件不是简单按钮,内部有复杂状态。比如一个秒杀倒计时组件,策划想配置“倒计时结束后,自动跳转到下一场活动”。这个时候组件内部并没有原生click,倒计时结束是组件自己的逻辑,怎么办?
解决方法是:程序员在自定义组件里声明可以暴露的事件钩子。我的做法是在组件配置元数据里增加一个events列表,用数组描述组件支持哪些事件:
javascript复制{
name: "CountDown",
events: [
{ name: "countdown_end", label: "倒计时结束", params: [{ name: "remain_seconds", label: "剩余秒数" }] },
{ name: "tick", label: "每秒跳动", params: [{ name: "current", label: "当前秒数" }] }
]
}
配置平台读取这段元数据后,会在触发器下拉框里自动出现“倒计时结束”“每秒跳动”选项。策划配置“倒计时结束跳转”,运行时组件内部会在倒计时结束时触发对应事件,而组件本身不需要关心“是谁订阅了这个事件”。这就是程序里的自定义事件机制,只不过把接口暴露给了配置层。
如果没有提前暴露钩子,就只能让程序员在组件里写一堆全局事件分发代码,比如通过事件总线emit一个“countdown_end”。但这种方式容易导致事件命名混乱,也不好维护。我的建议是:凡是需要给策划配置的组件,在设计文档里就要包含“可配置事件清单”,否则组件开发就不算完成。
2.4 配置粒度太大太小都会出事
配置粒度是产品设计里的一个平衡问题。粒度太细,策划每配一个交互都要填十几个步骤,学习成本高,最后策划还是选择提需求给程序员。粒度太粗,比如把所有交互都预置成固定场景,策划想加一个“并且条件”都做不到,一样会抱怨。
我见过一个折中方案,效果不错:内部把事件配置拆成三层。第一层是“高频场景模板”,比如“点击弹窗”“点击跳转”“滑到可视区埋点”,策划选择模板后只需要填少量参数,几分钟就能完成。第二层是“自由配置”,用上面说的触发源、条件、动作三个模块自由组合。第三层是“自定义动作”,当预置动作无法满足时,通过注册一个自定义动作插件实现。这样既保证了日常效率,又留了扩展空间。
这个分层思路也解决了团队里“要不要让策划配复杂逻辑”的争议。前两层覆盖70%以上的活动交互需求,第三层兜底剩下30%里的绝大部分,真正需要重新写一套交互逻辑的单子才会转到程序员手里。不要试图配置一切,那会让配置平台变成一个怪物。
3. 踩坑最多的六类问题,我们逐个救回来
3.1 事件冒泡:弹窗按钮点了却触发上一层的点击
做活动页时最常见的问题是嵌套交互。比如一个商品卡片,整卡可以点击进入详情,卡片上还有一个“点赞”按钮。策划配了“点击卡片跳详情”和“点击点赞按钮点赞”,结果测试发现:点击点赞按钮后,先弹了点赞成功,紧接着又跳进详情页。这就是事件冒泡——点点赞按钮时,事件冒泡到了卡片上,卡片的点击回调也被执行。
解决方式有两个层面。在配置系统层面,动作库里增加一个“阻止冒泡”独立动作,策划可以在配置“点击点赞”这条规则时,把这个动作拖进去,运行时它会在事件处理器里调用stopPropagation()。另外在触发源选择时,我规定“如果事件源是某容器内的子组件,必须确认是否同时绑定父容器的点击事件,如果有,建议在子事件中阻止冒泡”。这条规则写进了策划配置规范,问题出现率立刻下降了很多。
要注意的是,stopPropagation和preventDefault是两码事。preventDefault是阻止浏览器默认行为,比如点击链接跳转、右键菜单;stopPropagation是阻止事件继续传播。我在面板上用一个“阻止事件向上传播”开关来表达后者,而不是直接显示英文函数名。策划不需要理解冒泡原理,只需要知道“开了这个开关,点这个按钮就不会触发外层的东西”。
3.2 点击还是触摸:click和touch的恩怨
PC时代的click事件在移动端有300ms左右延迟,因为浏览器要判断你是不是想双击缩放。为了响应速度,很多移动端页面会用触摸事件touchstart/touchend模拟点击,但这也带来误触、滚动穿透、多指操作等新问题。早期配置系统直接给策划暴露click,结果在低端安卓机上体验很差;后来改成暴露touchstart,又出现用户滚动列表时手指划过按钮误触的情况。
最终我给配置系统提供的用户型触发器是:tap(单击)、doubleTap(双击)、longPress(长按)、touchStart、touchEnd。其中tap不是原生事件,而是由底层库统一处理的一种“无延迟、不误触”的抽象事件。策划只需要选“单击”还是“双击”,至于底层是click还是touch,由框架根据环境自动判断,不用策划关心。
这里要提醒一点:不要在配置面板里把click和touchStart同时暴露给策划。很多测试环境里,同一个点击动作可能同时触发了两个事件,引起逻辑重复执行。如果确实需要监听到“用户手指按下”这个瞬间,比如录音按钮,应该单独使用touchStart并显式屏蔽掉同源点击事件。否则建议统一用tap体系。
3.3 组件没渲染完,事件已经绑上
有一类问题特别隐蔽:策划配了“页面加载完成后,自动上报一次曝光”,但运行时发现有时候上报拿不到页面数据。原因是事件绑定的时机太早,页面框架虽然加载完了,但某个异步组件的业务数据还没回来。
我后来把系统触发器里的“页面加载完成”细分成三个:DOMContentLoaded(页面结构就绪)、页面数据就绪(首屏接口全部返回)、组件渲染完成。策划可以根据自己依赖的数据来源选择。另外在动作执行时,配置系统会先检查动作依赖的组件是否已经挂载,如果没有,会自动等待一个短轮询(比如每100ms检查一次,最多等3秒),超过时间就报出“事件动作执行超时”的日志。
这个改进看似简单,但解决了很多偶发的“为什么有时触发有时不触发”问题。排查这类问题的时候,不能只看事件是否绑定,还要关注数据是否就绪、组件是否可见、页面是否处于激活状态。把这些信息都同步进事件调试日志里,策划自己看日志就能清楚实际情况。
3.4 重复触发:用户狂点导致弹窗叠弹窗
配置系统上线后,测试提了一个尴尬的bug:连点按钮时弹窗叠了七八层,关闭一个又弹一个,整个页面卡死。原因很简单,策划配置的“点击弹窗”动作没有做防重,用户每次点击都会执行动作。
解决时我给动作库加了一个通用配置项:“动作执行间隔”,单位毫秒,默认是0。像弹窗、跳转、请求接口这种动作,把它默认设置成1000毫秒内不重复执行。同时在触发源配置上增加“点击后禁用按钮”选项,它会在事件触发后给按钮加上禁用态,直到动作执行完毕再恢复。这样策划不需要理解防抖和节流的差异,只需要按场景选择“单次触发”还是“可重复触发”。
这引出一个测试要点:事件配置不仅要在正常点击下通过,还要把“快速连点”“双指同时点”“多按钮同时触发”作为必测项。我在测试清单里专门加了一行“异常操作是否导致重复执行”。很多线上事故不是逻辑配错了,而是没考虑用户的极端操作。
3.5 异步时序:多个动作怎么排队
当一条事件挂了多个动作,动作之间可能有依赖关系。比如策划要配“点击按钮后,先发起登录态校验,校验通过再弹窗,弹窗关闭后再上报关闭埋点”。如果所有动作都在同一瞬间并行执行,一定不对。
我在运行时引入了一个轻量的执行队列。每一个动作都可以声明依赖条件,只有前面的动作满足指定状态,后面的动作才继续。界面上策划可以通过拖拽调整动作顺序,系统会提示“此动作依赖前一个动作的返回结果”。比如“请求接口”动作执行完毕后,会产出一个结果对象,后续动作里的条件字段可以直接引用到,例如“接口返回的code等于200时执行弹窗,否则显示Toast”。这个模型不复杂,但极大提升了策划能编排的交互复杂度。
当然也要防止策划排一个超级长的动作链,那样一旦前面某一步失败,后面全乱。所以我规定单个事件里的动作数量上限是10个,并且每个动作执行前都要有超时限制。出现某个动作失败时,系统默认中止后续动作,并在日志里标红。这样既保留了灵活,又限制了复杂度爆炸。
3.6 事件配置在线上出问题,怎么快速定位
配置系统做得再好,也总有配错的时候。以前排查问题靠程序员看控制台,现在策划也能自己配了,问题定位必须有工具支撑。我在后台加了一个“事件轨迹”面板,每一条用户发生的事件都会记录:事件源、触发类型、条件是否命中、命中后执行了哪些动作、各动作状态是成功还是失败、失败原因是什么。
这个面板用一个列表实时滚动显示,支撑运营和测试在真机上预览时查看。比如策划说“为什么点了没反应”,打开事件轨迹一看,发现事件确实触发了,但条件里的user.level > 3因为取到的是空值,判断结果为假,动作就没有执行。问题立刻定位到条件配置上,根本不需要麻烦程序员去翻代码。
另外每条配置都有一个全局唯一标识(配置事件ID),和需求单号关联。日志里会记录这个ID,出错时策划把ID贴给程序员,程序员直接通过ID查配置、查版本、查改动记录。这个习惯一旦养成,团队协作效率提升非常明显。不要再出现“你昨天是不是改了什么”这种对话了。
4. 协作流程:策划、设计、程序员怎么各司其职
4.1 策划负责“触发意图”,程序员负责“可配置能力”
配置系统不是把程序员干掉,而是把职责重新划分。策划的核心责任是描述清楚“用户做了某个动作后,业务期望发生什么”,这个描述应该用流程图或用例图表达,而不是写代码。程序员的核心责任则是沉淀业务中的可配置能力:哪些字段可以选、哪些动作可以复用、哪些事件可以暴露。
我在团队里推行过一个简单的规则:新需求进入评审时,先由策划用“如果……就……”句式把交互逻辑说清楚。如果这个逻辑能够用现有配置项表达,就直接进配置,不需要排期;如果部分不能表达,就在配置系统里登记一个“能力缺口”,由程序员评估是加一个预置动作还是加一个事件钩子。这个规则让需求评审从“能不能做”变成了“怎么扩充配置能力”。
这背后有一个心态转变:程序员的不写代码,不是降低存在价值,而是把精力投入到更多有复利效应的事情上。比如把组件生命周期管理好、把客户端的性能监控做好、把配置系统的可观测性做好。代码量不变,但价值密度高了很多。
4.2 配置规范:命名、版本、备注一个都不能少
多名策划同时操作一个配置平台,如果没有规范,几天后就会变成混乱现场。我吃过亏,所以后来强制推行了三条规范:命名规范、版本规范、备注规范。
命名规范是每一条事件配置必须有可读名称,格式建议为模块_位置_行为_目标,例如home_banner_click_show_popup。虽然平台会生成唯一ID,但可读名称是给人看的。版本规范是所有配置都走草稿、提交、发布流程,发布后可回滚。总会有策划把条件配反了,结果线上活动跑了半天,有版本管理就能秒回滚。
备注规范要求记录配置变更的意图,比如“新增VIP用户限制,活动规则变更,录入人:某策划”。这个备注会显示在事件轨迹和审批记录里,方便后续追溯。配置平台不只是一个工具,更是一个团队的知识库。规范做得好,新人接手也能快速理解每一段配置的来龙去脉。
4.3 设计师应该参与哪些环节
很多人觉得配置系统是策划和程序员的事,设计师可以靠边站。其实设计师在事件配置里同样扮演重要角色,特别是交互反馈状态的视觉表现。比如按钮点击时的按压态、弹窗出现时的遮罩透明度、Loading动画的样式、Toast的停留时间,这些都应该成为配置系统里“动作参数”的一部分。
我在做配置平台时,专门把“样式动作”设计成独立的动作类型。设计师可以在后台维护一组视觉模板,配置事件时直接引用模板。例如“弹窗”动作引用一个由设计规范定义好的弹出动画模板,而不是让策划临时填一堆CSS参数。这样既保证了视觉一致性,又让设计师不用接触代码也能控制交互细节。
同时,设计师要参与事件触发的验收。策划配完事件后,第一时间给设计师过一遍视觉和交互细节,尤其是边界状态:加载中、空数据、超长文案、弱网环境。设计师的关注点能给配置系统带来很多训练样本,让预置动作越来越好用。我的体会是,当设计师也能看懂配置面板上的“触发源/条件/动作”时,团队的沟通障碍就少了一大半。
4.4 策划验收自测清单
配置平台给了策划很大的自由度,但自由度也意味着责任。我在团队里整理了一份验收自测清单,策划在把配置提交发布前必须逐条跑一遍,减少线上返工:
- 正常路径:按预期操作,事件是否触发,动作是否执行。
- 条件边界:等于、大于、小于、为空、非空这些临界值是否都测过。
- 重复操作:连点、快速滑动、多点同时触发,是否出现重复执行或崩溃。
- 依赖数据:依赖的接口失败、超时、返回空值时,系统行为是否符合预期。
- 组件状态:页面刚加载、滚动到目标区域、组件未渲染完成时,事件是否报错。
- 回退场景:从页面A跳到页面B再返回,事件是否重复绑定或失效。
- 多端适配:PC、手机浏览器、App内嵌WebView,点击延迟和触觉反馈是否一致。
这份清单不需要很长,但每个问题都对应了真实踩过的坑。策划一开始嫌麻烦,后来发现跑完清单再提交,返工率降了一大半。程序员也终于不用随时被拉去“复现一下看看”了。
5. 一点真心话:让“不写代码”真正成立
5.1 不要指望策划配出复杂逻辑
配置系统做得再完善,也不要试图让策划写出复杂的业务逻辑。比如多步骤引导、需要会话状态流转的流程、涉及多接口串联的强一致性操作,这类东西还是应该交给程序员在代码层面实现。配置系统最适合处理的是“触发—条件—动作”这种相对直接的行为逻辑。
我见过一些团队过度追求“可视化编程”,把流程图引擎塞给策划,最后策划写出了谁也看不懂的巨型分支。这是在透支工具的易用性。一定要记住,策划不写代码的核心价值是快速响应业务变化,而不是成为另一种程序员。设计配置系统时,能用预置动作解决的,绝不让策划去连线。
5.2 配置系统本身就是一个产品,要持续迭代
配置系统不是做完一次就完事。我每个月都会整理一次策划高频使用但配置繁琐的场景,看哪些可以沉淀成模板;每季度会统计哪些动作被创建次数最多、哪些动作长期没人用。没人用的动作要么是入口难找,要么是场景过期,需要清理或优化。
配置系统的迭代也应该有版本和发布计划,不能天天偷偷改字段。我踩过一个大坑:有一次悄悄调整了条件操作符的英文映射,导致已上线活动在运行时判断错误,用户行为变形。从那以后,凡是涉及数据结构、字段含义的改动,都走完整的测试和发布流程,同时在配置面板上给出兼容性提示。用做产品的心态来维护这个工具,它才能真正成为团队的基建。
