抖音前端团队维护的 Semi Design 又推了一个实用版本。v2.97.0 的更新不算大张旗鼓,但其中一项改动——Cascader 组件新增 remote 属性——直接解决了一个长期痛点:级联选择器做远程数据加载时,开发者需要自己拼异步逻辑、手动管理 loading 状态和数据回填。现在这些都可以交给组件本身处理了。
下面挑几个值得关注的改动展开说。
Cascader 远程搜索:从手写异步到声明式配置
之前用 Semi Cascader 做远程搜索,大致流程是:监听 onSearch,自己发请求,拿到数据后 setState 更新 options,还要处理 loading 态、空态、防抖……代码量不少,且每个项目写法各异。
v2.97.0 引入 remote 属性后,只需要告诉组件"我是远程模式",再配上 onSearch 回调返回数据即可,loading 和空提示由组件内置处理。
一个最小可运行示例:
import { Cascader } from '@douyinfe/semi-ui';
function RemoteCascaderDemo() {
// 模拟远程请求,实际项目中替换为真实 API
const fetchOptions = async (searchValue) => {
if (!searchValue) return [];
const res = await fetch(
`https://example.com/api/cascader/search?q=${searchValue}`
);
const data = await res.json();
// 返回格式需符合 Semi Cascader 的 options 结构
return data.map((item) => ({
value: item.id,
label: item.name,
children: item.subCategories?.map((sub) => ({
value: sub.id,
label: sub.name,
})),
}));
};
return (
<Cascader
remote
onSearch={fetchOptions}
placeholder="输入关键词搜索分类"
style={{ width: 300 }}
/>
);
}
关键点:
remote一旦设置,Cascader 进入远程模式,不再依赖静态options。onSearch返回 Promise,组件自动等待并渲染 loading。- 搜索值为空时,可以返回空数组或不触发请求,组件会展示空态提示。
- 如果需要默认值回填,仍可通过
value+initOptions配合使用。
实际接入时,建议加上防抖和错误处理:
import { Cascader } from '@douyinfe/semi-ui';
import debounce from 'lodash/debounce';
function ProductCategoryPicker() {
const debouncedFetch = debounce(async (searchValue, callback) => {
try {
const res = await fetch(`/api/categories?q=${searchValue}`);
const data = await res.json();
callback(data);
} catch (e) {
callback([]); // 出错时返回空,避免组件卡在 loading
}
}, 300);
return (
<Cascader
remote
onSearch={(inputValue) =>
new Promise((resolve) => debouncedFetch(inputValue, resolve))
}
placeholder="搜索商品分类"
style={{ width: 320 }}
/>
);
}
其他值得留意的更新
除了 Cascader remote,这个版本还有一些小但实用的改动(具体列表以官方 changelog 为准):
- 组件 bug 修复:若干边界场景下的渲染或交互问题被修正,比如特定条件下下拉面板定位偏移、表单校验时序等。如果你之前遇到过类似问题,升级后可以验证是否已解决。
- 样式与主题微调:部分组件的默认样式 token 值有调整,如果项目使用了自定义主题,升级后建议跑一遍视觉回归。
升级实操建议
升级本身很简单:
# npm 项目
npm install @douyinfe/semi-ui@latest @douyinfe/semi-icons@latest
# yarn 项目
yarn add @douyinfe/semi-ui@latest @douyinfe/semi-icons@latest
升级后建议做这几件事:
- 跑一遍现有 Cascader 用法:如果项目里已有手写远程搜索的 Cascader,对照新 API 替换,代码量通常能砍掉一半。替换时注意
onSearch的返回格式必须符合 options 结构。 - 检查自定义主题:用 Semi Design Theme Builder 生成的主题包,重新导出一次,确保 token 值与新版本对齐。
- 回归测试表单场景:如果项目大量使用 Semi Form + Cascader/Select 等组合,跑一遍端到端测试,确认校验和联动逻辑无异常。
一个取舍提醒
remote 模式下,Cascader 的数据完全由搜索驱动,不会预加载整棵树。这对大数据量场景是好事——避免一次性拉取几万条分类数据;但对需要"先展示顶层分类,再逐级展开"的场景,你可能仍需用 loadData(懒加载)而非 remote(搜索驱动)。两者区别:
| 模式 | 触发方式 | 适用场景 |
|---|---|---|
remote |
用户输入关键词 | 搜索为主,数据量大,用户知道要找什么 |
loadData |
用户逐级展开 | 层级浏览为主,数据量可控,用户需要探索 |
选错模式会让交互变得别扭,别盲目追新特性,先想清楚用户的使用路径。
Semi Design 这类迭代节奏——小版本持续补齐组件的异步/远程能力——对中后台项目来说是实打实的收益。如果你正在用 Semi,这个版本值得升级;如果还没用过,Cascader remote 这种"开箱即用"的异步支持,是评估一个 UI 库成熟度的好指标。