Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。
文章代表作者个人观点,少数派仅对标题和排版略作修改。
之前 我在探索 Airtable 时曾经实现过一个用户旅程地图,有不少小伙伴对这其产生了很大的兴趣,纷纷问我这是个什么软件,能不能体验或者使用。
但是由于这个旅程图是 Airtable 上的 Custom App ,如果要使用必须得是 Airtable 的付费会员,且需要一定程度复杂的前置安装操作与配置,所以这个用户旅程地图虽然看上去和体验起来都还不错,但是上手的门槛实在有点高。
另外,从开发层面来看,这个组件的开发体验并不理想。原因有两点:
这也使得我在完成这个 demo 后,就丢在那边没有添加新功能和别的优化了。(当然另外一个重要原因也是我之前缺少相关的业务场景)
在最近一周左右的时间里,由于某些契机,我将这个用户旅程地图进行了一遍重构和一定程度的视觉优化,并将其提取成了一个 组件,进而可以在网页、Airtable、甚至 Sketch 插件中作为模块引入,灵活性也大大增强。
在这个过程中, 我无意间探索出一种有意思的工具开发与资产沉淀的模式, 在这分享出来,和大家做个探讨 。
首先按照国际惯例简单介绍一下这个新鲜出炉的东西。说实话我无法用传统的「组件」、「产品」或者「应用」、「工具」来完美描述我做的这个玩意,可能比较合适的说法是「方法」、「流程」或者「服务」?
欢迎在看完后为它下定义,不过为了方便起见,在本文里还是用「应用」这个词吧。
这是一种用文本语言来书写用户旅程地图的(如下图所示)应用,你可以通过书写结构化与语义化的文本,轻松地实时生成用户旅程地图。
我做的这件事情最早的缘起应该是在我之前实习时的一次周会。组里一位同学在完成一个冲刺项目的设计闭关后,和大家分享了一张在设计前期与多名 PD 同步时制作的产品流程图,在分享完毕后,大家交流起来。
我主管问:「问个有意思的问题,你这张图在从第一次做完之后,还有在迭代吗?」
同学回答说:「做了一些视觉上的微调,后面就没动了。」
在得到否定的回答后,他就提了一个很有意思的问题:「大家可以想想, 如何使得我们在设计前期做的各种图(产品流程图、用户旅程地图、服务蓝图等等)在做完之后不变成一张死图?」
然后大家讨论了各自的一些思路,比较经典的应该是利用语雀的表格来进行绘制,但是限制也相对较大。到最后我们也没有讨论出一个非常完美的方案,就干脆进入了下一个话题。
我相信用 Sketch 画过这些流程图的设计师应该深有体会,这种图的绘制往往费时费力,而且一旦需要修改,往往非常费力,心智负担很大。这也就导致很多时候除了展示(写文章、晋升述职)以外,就不会再去迭代更新这些做出来的图,而随着时间流逝,项目可能发生了变化,而我们又并没有及时更新,最后当时花了大量时间制作的图就变成了死图。
作为一名 「懒癌晚期患者」,我对于这类问题非常感兴趣。因为我及其厌恶所有工作效率低下的繁琐流程和操作,所以我会竭尽自己所能优化自己的工作流,提升效率。针对他提出来的这个问题,当时也没有想出什么好的办法来,所以暂时作罢。
在去年遇到 Airtable 时,我惊奇地发现利用 Airtable 和它的 App 可以非常完美地解决上述场景下的这个问题,并将它分享了出来。但这个完美的前提,则是需要会使用 Airtable,且开通 Airtable 的付费会员。在上周将其组件化与重构的过程中,我萌生了能否让该组件脱离 Airtable 也可单独使用的想法。在进行了相关的探索后,就有了现在的这个模样。
体验该应用最快速的方法,就是打开上图这个 模板。我会基于这个模板简单介绍一些基础用法,让大家对这个应用有个直观的体感。关于具体的使用教程就不在这里赘述,想详细了解的小伙伴请移步:使用教程 。
在该应用的左侧编辑器中修改所有绿色文本和黄色数字时,右侧的界面会实时自动刷新。
然后也可以通过复制文本来快速创建一个用户行为。(图中的快捷键是 alt
+ shift
+ ↑
,代表向上快速复制选中的文本)
也可以通过注释掉某一阶段,将其在图中隐藏。(快捷键 CMD
+ /
)
针对一些个性化需求,我也提供了一些配置选项,例如可以在 sections 下面调整显示的区块。(移动文本的快捷键为 alt
+ ↑
或 ↓
)
也可以通过 height
配置项自定义某些区块的高度。
文档平台在某意义上是就是旅程图的「终端」。在 CodeSandbox 渲染出来的图集成到文档平台时,才可以发挥出 这个图 的最大价值。(如下所示)
关于如何嵌入到文档平台,请查阅:
简单介绍完这个应用后,来聊聊这个应用背后整个的思考过程,个人认为这才是这个应用背后最有意思的环节。
在这项工作开始之初,我只是想把之前在 airtable 中的 app 提取成一个组件,这样就可以提高开发效率和体验。在我完成初步组件化之后,只需要从外部传入 JSON 数据,就可以渲染出相应的旅程图,如下图所示。
需要传入的数据示例如下:
import { JourneyMapData } from '@arvinxu/journey-map';
type Steps = 'plan' | 'rent' | 'take' | 'play' | 'return';
export const data: JourneyMapData<Steps> = {
stages: [
{
id: 'plan',
name: ' 计划租车 ',
},
{
id: 'rent',
name: ' 租车 ',
},
{
id: 'take',
name: ' 提车 ',
},
{
id: 'play',
name: ' 游玩 ',
},
{
id: 'return',
name: ' 还车 ',
},
],
actions: {
plan: [
{ name: ' 找租车平台 ', emotion: -1 },
{ name: ' 对比不同平台 ', emotion: -2 },
{ name: ' 确定平台 ', emotion: 1 },
],
rent: [
{ name: ' 选择租车日期 ', emotion: -1 },
{ name: ' 与同伴讨论车型 ', emotion: -1 },
{ name: ' 选择租车类型 ', emotion: 0 },
{ name: ' 支付费用 ', emotion: 1 },
],
take: [
{ name: ' 打车去提车点 ', emotion: 2 },
{ name: ' 确认提车时间和地点 ', emotion: 2 },
{ name: ' 确认车况 ', emotion: 2 },
{ name: ' 确认还车注意事项 ', emotion: 1 },
{ name: ' 取车离开 ', emotion: 2 },
],
play: [
{ name: ' 返回接同伴 ', emotion: 2 },
{ name: ' 开车游玩一天 ', emotion: 0 },
{ name: ' 车出了问题 ', emotion: -2 },
{ name: ' 打电话给客服 ', emotion: -1 },
{ name: ' 处理车况 ', emotion: 2 },
],
return: [
{ name: ' 加油站加油 ', emotion: -1 },
{ name: ' 确认使用车况 ', emotion: -1 },
{ name: ' 打车返回 ', emotion: 0 },
{ name: ' 完成车辆交接 ', emotion: 1 },
],
},
};
由于我使用了 dumi 作为组件开发的文档框架,因此在我发布完组件包后,经常会用 CodeSandbox 来确认组件是否可以被正常使用。
CodeSandbox 是一个在线的代码编辑器,主要聚焦于创建 Web 应用项目。
支持主流的前端相关文件的编辑:JavaScript、TypeScript、CSS、Less、Sass、Scss、HTML、PNG 等。支持自动代码提示。
关于 CodeSandbox 的介绍和使用,欢迎查看:CodeSandbox 使用指南
当在 CodeSandbox 中打开上述 示例 时,我突然意识到: 如果依托于 CodeSandbox,将 JSON 数据以文本的形式记录下来,那么这个旅程图就可以与 Airtable 完全解耦! 而一旦解耦之后,使用该旅程图的门槛就会大大降低,进而真正有潜力变成生产力工具。
当我脑子有了这个念头之后,我突然又想到了之前实习时做的一个小东西——图片画廊(太小了以至都没单独为它写文章)。
这个组件希望尝试解决的问题是,图片类素材在团队中如何有效地分发、管理和使用。
而这个组件的数据源也和用户旅程图也非常类似,也是采用 JSON 的形式,将数据保存到文本中。
这个组件的设计加开发用时差不多 两三小时,至于代码也就短短百行左右,但是结合内部的一个代码托管平台,就可以嵌入到语雀中,作为图片素材的管理中心文档,恰到好处地解决了痛点问题。
结合之前做到一半的 Mindflow,把这三个东西放在一起时,我突然意识到了一种潜在的 「数据文档」 搭配 「可视组件」的「组件应用」。
组件应用,顾名思义,就是应用的主体就只包含一个组件。由于只包含有一个组件,所以开发成本比起完整 App 要低很多很多(甚至在大部分时候可能只需要完成视图的展示即可),同时通过该组件又满足了该场景下绝大部分需求。
但是我们知道,只有组件是没法对数据持久化的。那数据的存储该怎么办呢?这就要交给前面所提到的「数据文档」了。「数据文档」指的是将之前存到数据库里的数据(一般为 JSON),以文档的形式进行保存。这样一来,所有对数据增删改查的交互操作,则全部由文本编辑器来兜底。
这里还有个小问题:在前端组件中,数据通过 JSON 进行存储,但是 JSON 是一种机器化的数据结构,非常不易于人类阅读与书写(如下图左侧所示)。如果数据文档用 JSON 保存,那么对人类来说会非常不友好。
所以这就引入了数据文档的主角:YAML。YAML 在开发中是专门用来写配置文件的语言,非常简洁和强大。通过非常简单的语法,就可以写出丰富的文档结构。
同一数据内容的 JSON 与 YAML 的对比
在 JSON 中需要用大量的引号、大括号、中括号和逗号才能表达的数据,在 YAML 通过缩进和 -
就可以表达,因此 YAML 是一种非常易于用户书写和阅读的语言。(如果你了解 Markdown,那么你就能理解 YAML 与 JSON 的关系 ——YAML 相当于 Markdown ,而 JSON 相当于 HTML)
写 YAML 文档在很大程度上和书写普通的文档没有太大的区别,只是需要注意一定的结构规范(即 YAML 的语法和用户旅程图相应的语法),例如:
stages:
- name: 计划租车
actions:
- name: 找租车平台
emotion: -1
- name: 对比不同平台
emotion: -2
thoughts:
- 对比来对比去好麻烦
painPoints:
- 能否有一个一键对比的能力
- name: 确定平台
emotion: 0
thoughts:
- 感觉一嗨好像还不错
- 神州好贵
painPoints:
- 手机上操作效率太低了
虽然上述示例好像存在一些看不懂的英文,但事实上将它们简单翻译一下(stages:阶段、name:名称、actions:行为、emotion:情绪值、thoughts:想法、painPoints:痛点),就会发现其实是就是一些人话:
阶段:
- 名称: 计划租车
用户行为:
- 名称: 找租车平台
情绪值: -1
- 名称: 对比不同平台
情绪值: -2
想法:
- 对比来对比去好麻烦
痛点:
- 能否有一个一键对比的能力
- 名称: 确定平台
情绪值: 0
想法:
- 感觉一嗨好像还不错
- 神州好贵
痛点:
- 手机上操作效率太低了
我相信这样的数据文档,是任何一名设计师都可以轻松学会的。 而事实上,在我看来,使用 YAML 书写用户旅程地图的数据文档,和我们写普通的 Markdown 没有什么太大区别,只需要遵循一定的语法规范即可。这样一来,我们就可以使用这种符合规范的「数据文档」,在「组件应用」中得到相应的用户旅程地图。
文本编辑的交互是最自由的手段。而基于 VSCode 编辑器框架开发的 CodeSandbox 包含了大量文本编辑的高效交互。 虽然可能的确不如可视化编辑器那么直观,但是一旦上手后效率奇高无比,一些在传统应用中无法做到的调整需求,都可以用文本编辑器快速达成。因为 CodeSandbox 集成了 VSCode 的编辑器框架,因此大部分使用 VSCode 的编辑技巧都可以用在 CodeSandbox 中,下面就举了两个例子。(感兴趣的小伙伴可以自行查阅相关技巧,我在这里就不写了)
注释
采用文本编辑的很大的好处就是可以利用注释(标记符 #
)来承载数据之外的信息,例如这张图是在,则可以在顶部加入与会人员、时间等信息,针对某些具体的阶段,也可以补充必要的相关信息。而这在传统的旅程图工具、或者其他各种非文本类的工具中可能都没有非常好的备注方案。
代码块折叠
YAML 可以算是一种语言,因此 CodeSandbox 会将我们书写的文档当成代码来着色,譬如关键字是红色,注释是灰色,字符串是绿色、数值是橙黄色。同时这样一个文档也具有了折叠与展开能力(如下图所示)。这样一来,哪怕文档多长,我们都可以用代码折叠的方式将注意力聚焦到关注的文档块中。
同时,CodeSandbox 提供了 10+ 关于折叠与展开的快捷键,帮助我们提效(红色框出来的是算比较常用的)
在传统的云端应用(例如 Figma 等)中,我们往往需要将数据保存到后端数据库中,数据的展示界面是一个完整的应用产品,包含登录注册等区分用户的基本流程。而在传统的桌面端应用中(例如 Sketch),该应用往往会自定义一种文件后缀形式,将其与应用进行关联绑定,文件的读取、修改、存储都由软件来控制。
「数据文档」搭配 「组件」的「组件应用」,则是介于两者之间,是一种适合低频、小众场景的应用解决方案。简单对比如下:
云端应用 | 桌面端应用 | 组件应用 | |
数据存储 | 无 | 保存为自定义本地文件 | 纯文本 |
三方兼容度(是否可用别的工具修改) | 往往无法兼容 | 视应用而定 | 可用任何文本编辑器修改 |
修改方式 | 只能借助应用界面 | 视应用而定(例如 Sketch 借助界面,而 Typora 就可以用三方编辑器修改) | 文本编辑器(无法用界面) |
视图形式 | 自定义 | ||
开发成本 | 高 | 高 | 低 |
交互操作 | 受应用本身限制 | 受应用本身限制 | 采用文本编辑器交互 |
在完成用户旅程地图这个「组件应用」后,我还进一步探索和思考了一下用户旅程图组件的应用可能性:
对于这样一个「组件应用」,大家有什么想法呢?欢迎在评论区 「做梦」,说不定我哪天就把它们实现了呢~😏
前段时间看到 《你的下一个应用,未必是程序》,其中有一段话让我深有共鸣:
因此,与其关注应用是什么,不如关注应用能做到什么、是如何做到的、有没有尊重我们的选择和权利。与其关注一个应用是工具还是服务、原生还是「套壳」、买断还是订阅,不如关注它能否满足需求、提高效率、创造价值。
抽象意义上来说,「应用」是对特定场景的一组功能集合,来满足该场景下的需求、提升效率、创造价值。而在各种应用、SaaS 服务大行其道的今天,多少应用开始主动或被动地偏离这种初衷。毕竟一个完整的应用无法完全聚焦在功能本身。为了提供相应的服务,往往还需要用户体系、数据存储等各种其他功能模块。这一方面提高了自身的开发成本,又在另一方面在信息流动的过程中不自觉地竖起了一堵堵高墙,一点点阻碍了多种应用间协作的可能性。而我现在探索的「组件应用」,说不定就是一种「应用」新方向了,对于足够轻量化和小众的场景,也许可以试试这样的模式。
说不定在未来, 你的下一个应用,就未必是现在的「应用」了。
《小岛经济学》里中有个非常打动我的故事:
从前,有三个人一艾伯、贝克和查理住在一座岛上。岛上的生活艰苦,他们三个人只能每天打渔,然后吃鱼。一开始的时候,每个人用一天的时间只能打到一条鱼,而填饱肚子,也正好需要一条鱼。
有一天,艾伯突然有个灵感,想做个捕鱼器,这样就可以尝试捕鱼的新方法,有了这个捕鱼器,捕鱼的时间就能缩短,这样再也不会饿了。但是为了织这个渔网,艾伯需要挨一天饿。
查理得知艾伯的想法后,惊得眼珠直转,他想自己的朋友肯定是疯了。「你疯了,这样做,我告诉你,要是你这捕鱼器不好使,可别哭着来跟我要鱼吃,一片也别想。我头脑清醒,但这并不表示我会为你的疯狂做法埋单。」
艾伯没有被査理的话吓倒,仍然继续织网。到这一天结束时,艾伯终于织完了自己的渔网。
而第二天,其他人还是只能打到一条鱼,而艾伯打到了好几条鱼。
作者讲完这个故事后做了一个提纲挈领的总结: 通过自我牺牲(也就是挨饿),艾伯创造了资本。
现在普遍的观点认为都「去上班就是在出卖自己的劳动力,就是被资本持续地剥削」,而这种观点虽然没有什么大问题,但是可能过于消极了。可能由于我们已经过了生产力极度贫乏的阶段,所以大家渐渐将资本直接等同于金钱,进而忽略掉了资本最初诞生时的模样。
小岛经济学用非常生动形象的故事告诉我们,我们任何提高效率的尝试和努力,所形成的「效率工具」、「工作流」或者「方法」,其实都是在「创造资本」。虽然它们不是真金白银,但是这其实才是资本原来的模样。
回溯我最早创造的「资本」,可能是从高中开始,因为我们高中 学习时间有限,因此对效率要求非常高。所以我在这些过程中逐步摸索了出了很多 经验技巧,最终在高考中得以如愿。
哪怕到现在为止,我依旧保持着对效率的极度追求,在这个追求的过程中也不断创造着新的「资本」,这个用户旅程地图就是如此。这么多年无数积累下来的资本,让我具有了很高的工作效率和产出,让我有足够的底气面对任何工作,我想这说不定也是当下的一种破局之法吧。
> 下载少数派 客户端 、关注 少数派公众号 ,了解更妙的数字生活 🍃
> 想申请成为少数派作者?冲!
© 本文著作权归作者所有,并授权少数派独家使用,未经少数派许可,不得转载使用。