单元格Cell
列表的基本单元:一行里承载「标题 + 说明 + 值 + 箭头」,可整行点击进入下级
数据展示 规格 7 · 单元格 Cell 6 端实现 触摸优先
<!-- ① 令牌:PC 令牌 + 移动端 --kole-m-* 合成单文件,引一次 -->
<link rel="stylesheet" href="kole-ui/mobile/tokens.css">
<!-- ② 本组件样式(全量则用 kole-ui/mobile/components/index.css) -->
<link rel="stylesheet" href="kole-ui/mobile/components/cell.css">
<!-- ③ 结构照抄下方任一演示块(类名与 6 端实现一致) -->
演示
每个演示都是真实渲染:预览帧加载 frameworks-mobile/Cell.html?demo=<id>(只显示该演示块),代码是该演示块在演示页里的原文,可复制。全部演示同屏可看 演示页 ↗。
01 组件类型
标题 + 右侧值 + 箭头,最常见的可点单元格。
查看代码(演示页原文 · 11 行)
<section class="demo-block" data-demo="basic">
<p class="demo-label">基础用法(link + arrow:整行可点,带箭头)</p>
<div class="demo-box">
<button class="kole-m-cell kole-m-cell--link" type="button" id="cell-link"
data-assert="cell-basic" data-behavior="click-sets-attr:#cell-link|data-clicked|true">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">收货地址</span></span>
<span class="kole-m-cell__value">杭州市余杭区</span>
<span class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
</div>
</section>两行文字(主 + 副),副标题单行省略。
查看代码(演示页原文 · 12 行)
<section class="demo-block" data-demo="desc">
<p class="demo-label">带副标题(两行文字,副标题单行省略)</p>
<div class="demo-box">
<div class="kole-m-cell" data-assert="cell-desc">
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">订单编号</span>
<span class="kole-m-cell__desc">20260920-001 · 2026-09-20 09:12 创建</span>
</span>
<span class="kole-m-cell__value">已发货</span>
</div>
</div>
</section>右侧放开关、标签等非文字内容(此处用标签示意)。
查看代码(演示页原文 · 9 行)
<section class="demo-block" data-demo="custom">
<p class="demo-label">自定义右侧(右侧放标签等非文字内容)</p>
<div class="demo-box">
<div class="kole-m-cell" data-assert="cell-custom">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">发票抬头</span></span>
<span class="demo-tag">已开票</span>
</div>
</div>
</section>02 组件状态
一组单元格共享分隔线;组内最后一条用 borderless 收尾。
查看代码(演示页原文 · 15 行)
<section class="demo-block" data-demo="group">
<p class="demo-label">分组列表(组内共享分隔线,最后一条 borderless 收尾)</p>
<div class="demo-box">
<button class="kole-m-cell kole-m-cell--link" type="button" data-assert="cell-group-1">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">支付方式</span></span>
<span class="kole-m-cell__value">微信支付</span>
<span class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
<button class="kole-m-cell kole-m-cell--link kole-m-cell--borderless" type="button" data-assert="cell-group-2">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">配送方式</span></span>
<span class="kole-m-cell__value">顺丰标快</span>
<span class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
</div>
</section>置灰且不响应点击(无权限项的常见表达)。
查看代码(演示页原文 · 12 行)
<section class="demo-block" data-demo="disabled">
<p class="demo-label">禁用(无权限项:置灰且不响应)</p>
<div class="demo-box">
<div class="kole-m-cell is-disabled" data-assert="cell-disabled" aria-disabled="true">
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">企业认证</span>
<span class="kole-m-cell__desc">需要管理员权限</span>
</span>
<span class="kole-m-cell__value">暂无权限</span>
</div>
</div>
</section>API
props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs
Props
| 名称 | 类型 | 默认值 | 说明 | 必传 |
|---|---|---|---|---|
title | string | '' | 主标题,单行省略(规格 §7.2) | N |
desc | string | '' | 可选副标题,单行省略(规格 §7.2) | N |
value | string | '' | 右侧值或状态文字(规格 §7.2) | N |
arrow | boolean | false | 变体 arrow:显示右箭头表示可进入(规格 §7.3) | N |
link | boolean | false | 变体 link:整行可点(规格 §7.3) | N |
borderless | boolean | false | 关掉底部 1px 分隔线(规格 §7.5) | N |
disabled | boolean | false | 置灰且不响应(规格 §7.4) | N |
「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。
事件
| 名称 | 参数 | 说明 |
|---|---|---|
click | — | 可点单元格(link=true)点击时触发 |
插槽
| 名称 | 说明 |
|---|---|
default | 右侧自定义内容,替代 value(规格 §7.2) |
icon | 可选左侧图标(规格 §7.2) |
CSS 变量
组件级变量(在组件样式表里定义)。业务侧可在自己的作用域内覆盖,不必改组件源码。
| 名称 | 默认值 | 说明 |
|---|---|---|
| 本组件没有组件级 CSS 变量 | ||
何时使用
- 列表的基本单元:一行里承载「标题 + 说明 + 值 + 箭头」,可整行点击进入下级
- 可点单元格整行都是热区,高度不小于 56px
- 按下反馈是整行背景变化,不是只有文字变色
- 单元格之间默认有 1px 分隔线,可用 borderless 关掉
交互与触控
- 可点单元格整行都是热区,高度不小于 56px
- 按下反馈是整行背景变化,不是只有文字变色
- 单元格之间默认有 1px 分隔线,可用 borderless 关掉
无障碍
- 可点单元格用原生 button;纯展示单元格用 div
- 值区只作展示时不要放进可聚焦元素
相似组件
从「该用哪一个」的角度区分;PC 端的对应实现见 PC 文档站。
| 组件 | 何时用它而不是本组件 |
|---|---|
| 滑动单元格SwipeCell | 行内还需要滑动操作时用滑动单元格;只进入下级用普通单元格 |
| 动作面板ActionSheet | 点击单元格后需要提供多个动作时用动作面板;单一跳转保留单元格语义 |
规格未定 / 禁止发明
| 类别 | 条目 |
|---|---|
| 禁止发明 | 多行标题的折叠规则 |
| 禁止发明 | 单元格内多列布局的栅格规则 |
| 规格未定 | 副标题最多显示几行 |
| 规格未定 | 右侧值超长时的截断策略 |
结构(anatomy)
| 字段 | 说明 |
|---|---|
cell | 根元素,一行两类内容(左侧主区 / 右侧值区) |
title | 主标题,单行省略 |
desc | 可选副标题,单行省略 |
value | 右侧值或状态文字 |
arrow | 可选右箭头,表示可进入 |
icon | 可选左侧图标 |
变体维度与类名映射
类名映射由构建脚本从契约 variantClasses 生成,并被 verify:mobile-docs 逐条对照组件 CSS 校验(类/变量必须真实存在)。
| 维度 | 取值 | 对应类名 / 变量 |
|---|---|---|
arrow | false / true | false (由数据驱动,无专属类) true .kole-m-cell__arrow |
link | false / true | false (由数据驱动,无专属类) true .kole-m-cell--link |
代表变体
| 变体 | 标签 |
|---|---|
arrow=true · link=true | 可点单元格(带箭头) |
arrow=false · link=false | 纯展示单元格 |
arrow=false · link=true | 可点无箭头 |
arrow=true · link=false | 有箭头但不可点 |
用到的令牌
构建时从本组件样式表扫描得出。蓝色为移动端自有令牌,绿色为继承的 PC 令牌(改一处两端生效)。
6 端源码
同一组件的六份实现(生产环境的类名与结构一致,差异只在技术栈写法与单位)。点开查看,右侧可复制。
frameworks-mobile/Cell.css · 纯样式(CSS) · 72 行
/* Kole UI Mobile · Cell 样式 — 对齐移动端规格 §7
单元格:一行承载「标题 + 说明 + 值 + 箭头」,整行热区(高度 ≥ 56px),
按下反馈是整行背景变化;行间默认 1px 分隔线,可用 borderless 关掉。 */
.kole-m-cell {
display: flex;
align-items: center;
gap: var(--kole-space-8);
box-sizing: border-box;
width: 100%;
min-height: var(--kole-m-action-height);
padding: var(--kole-space-12) var(--kole-m-gutter);
border: 0;
border-bottom: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-body);
font-family: inherit;
font-size: var(--kole-m-font-size-body);
line-height: 1.4;
text-align: start;
}
/* 组内最后一条:关掉分隔线 */
.kole-m-cell--borderless { border-bottom-color: transparent; }
/* 变体 link:整行可点,按下反馈是整行背景变化 */
.kole-m-cell--link { cursor: pointer; touch-action: manipulation; }
.kole-m-cell--link:active { background: var(--kole-color-table-header-bg); }
.kole-m-cell:disabled,
.kole-m-cell.is-disabled {
color: var(--kole-color-text-disabled);
cursor: not-allowed;
}
.kole-m-cell:disabled:active { background: var(--kole-color-card-bg); }
.kole-m-cell__icon { flex: 0 0 auto; display: inline-flex; color: var(--kole-color-text-secondary); }
.kole-m-cell__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.kole-m-cell__title {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: var(--kole-color-text-title);
}
.kole-m-cell__desc {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: var(--kole-m-font-size-label);
color: var(--kole-color-text-secondary);
}
.kole-m-cell__value {
flex: 0 0 auto;
max-width: 45%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: var(--kole-m-font-size-label);
color: var(--kole-color-text-secondary);
}
.kole-m-cell__arrow { flex: 0 0 auto; display: inline-flex; color: var(--kole-color-text-placeholder); }
.kole-m-cell:focus-visible {
outline: 2px solid var(--kole-color-focus-ring);
outline-offset: -2px;
}
frameworks-mobile/Cell.html · H5 原生(无框架) · 118 行
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>Kole UI Mobile · Cell(H5)</title>
<link rel="stylesheet" href="../.design_library/kole-ui-mobile/colors_and_type.css">
<link rel="stylesheet" href="Cell.css">
<style>
body { margin: 0; background: var(--kole-color-page-bg); font-family: var(--kole-font-family); color: var(--kole-color-text-body); }
.demo { max-width: 375px; margin: 0 auto; padding: var(--kole-m-gutter) 0; }
.demo-label { margin: 0; padding: var(--kole-space-12) var(--kole-m-gutter) var(--kole-space-8);
font-size: var(--kole-m-font-size-label); color: var(--kole-color-text-secondary); }
.demo-box { background: var(--kole-color-card-bg); border-block: 1px solid var(--kole-color-border); }
.demo-tag { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 11px;
background: var(--kole-color-brand-bg); color: var(--kole-color-brand); font-size: var(--kole-m-font-size-caption); }
.demo-block[hidden] { display: none; }
</style>
</head>
<body>
<div class="demo">
<section class="demo-block" data-demo="basic">
<p class="demo-label">基础用法(link + arrow:整行可点,带箭头)</p>
<div class="demo-box">
<button class="kole-m-cell kole-m-cell--link" type="button" id="cell-link"
data-assert="cell-basic" data-behavior="click-sets-attr:#cell-link|data-clicked|true">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">收货地址</span></span>
<span class="kole-m-cell__value">杭州市余杭区</span>
<span class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
</div>
</section>
<section class="demo-block" data-demo="desc">
<p class="demo-label">带副标题(两行文字,副标题单行省略)</p>
<div class="demo-box">
<div class="kole-m-cell" data-assert="cell-desc">
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">订单编号</span>
<span class="kole-m-cell__desc">20260920-001 · 2026-09-20 09:12 创建</span>
</span>
<span class="kole-m-cell__value">已发货</span>
</div>
</div>
</section>
<section class="demo-block" data-demo="custom">
<p class="demo-label">自定义右侧(右侧放标签等非文字内容)</p>
<div class="demo-box">
<div class="kole-m-cell" data-assert="cell-custom">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">发票抬头</span></span>
<span class="demo-tag">已开票</span>
</div>
</div>
</section>
<section class="demo-block" data-demo="group">
<p class="demo-label">分组列表(组内共享分隔线,最后一条 borderless 收尾)</p>
<div class="demo-box">
<button class="kole-m-cell kole-m-cell--link" type="button" data-assert="cell-group-1">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">支付方式</span></span>
<span class="kole-m-cell__value">微信支付</span>
<span class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
<button class="kole-m-cell kole-m-cell--link kole-m-cell--borderless" type="button" data-assert="cell-group-2">
<span class="kole-m-cell__main"><span class="kole-m-cell__title">配送方式</span></span>
<span class="kole-m-cell__value">顺丰标快</span>
<span class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
</div>
</section>
<section class="demo-block" data-demo="disabled">
<p class="demo-label">禁用(无权限项:置灰且不响应)</p>
<div class="demo-box">
<div class="kole-m-cell is-disabled" data-assert="cell-disabled" aria-disabled="true">
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">企业认证</span>
<span class="kole-m-cell__desc">需要管理员权限</span>
</span>
<span class="kole-m-cell__value">暂无权限</span>
</div>
</div>
</section>
</div>
<script>
/* 演示页脚本:可点单元格被点击后打个标记(真实业务里是路由跳转) */
(function () {
var cell = document.getElementById('cell-link');
if (!cell) return;
cell.addEventListener('click', function () {
cell.setAttribute('data-clicked', 'true');
});
})();
</script>
<script>
/* ?demo=<id> → 只显示该演示块(文档站按块预览用;无参数时全部显示,测试与回归走无参数路径) */
(function () {
var id = new URLSearchParams(location.search).get('demo');
if (!id) return;
var blocks = Array.prototype.slice.call(document.querySelectorAll('.demo-block'));
var hit = false;
blocks.forEach(function (b) {
var on = b.getAttribute('data-demo') === id;
if (on) hit = true;
b.hidden = !on;
});
if (!hit) { blocks.forEach(function (b) { b.hidden = false; }); return; }
document.body.classList.add('demo-single');
blocks.forEach(function (b) {
var label = b.querySelector('.demo-label');
if (label && !b.hidden) label.hidden = true;
});
})();
</script>
</body>
</html>
frameworks-mobile/Cell.jsx · React · 61 行
import React from 'react';
import './Cell.css';
/* 单元格(移动端)— 规格 §7;link=true 时用原生 button(整行热区、可键盘聚焦) */
export default function Cell({
title = '',
desc = '',
value = '',
arrow = false,
link = false,
borderless = false,
disabled = false,
onClick,
children = null,
icon = null,
}) {
const cls =
'kole-m-cell' +
(link ? ' kole-m-cell--link' : '') +
(borderless ? ' kole-m-cell--borderless' : '') +
(disabled ? ' is-disabled' : '');
const inner = (
<>
{icon ? <span className="kole-m-cell__icon">{icon}</span> : null}
<span className="kole-m-cell__main">
<span className="kole-m-cell__title">{title}</span>
{desc ? <span className="kole-m-cell__desc">{desc}</span> : null}
</span>
{children || (value ? <span className="kole-m-cell__value">{value}</span> : null)}
{arrow ? (
<span className="kole-m-cell__arrow" aria-hidden="true">
›
</span>
) : null}
</>
);
/* 可点单元格用原生 button(规格 §7.6);纯展示用 div */
if (link) {
return (
<button
className={cls}
type="button"
disabled={disabled}
onClick={() => {
if (disabled) return;
if (onClick) onClick();
}}
>
{inner}
</button>
);
}
return (
<div className={cls} aria-disabled={disabled ? 'true' : undefined}>
{inner}
</div>
);
}
frameworks-mobile/Cell.vue2.vue · Vue 2 · 57 行
<template>
<button
v-if="link"
class="kole-m-cell"
:class="cellClass"
type="button"
:disabled="disabled"
@click="$emit('click')"
>
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">{{ title }}</span>
<span v-if="desc" class="kole-m-cell__desc">{{ desc }}</span>
</span>
<slot>
<span v-if="value" class="kole-m-cell__value">{{ value }}</span>
</slot>
<span v-if="arrow" class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
<div v-else class="kole-m-cell" :class="cellClass" :aria-disabled="disabled ? 'true' : null">
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">{{ title }}</span>
<span v-if="desc" class="kole-m-cell__desc">{{ desc }}</span>
</span>
<slot>
<span v-if="value" class="kole-m-cell__value">{{ value }}</span>
</slot>
<span v-if="arrow" class="kole-m-cell__arrow" aria-hidden="true">›</span>
</div>
</template>
<script>
export default {
name: 'KoleMCell',
props: {
title: { type: String, default: '' },
desc: { type: String, default: '' },
value: { type: String, default: '' },
arrow: { type: Boolean, default: false },
link: { type: Boolean, default: false },
borderless: { type: Boolean, default: false },
disabled: { type: Boolean, default: false }
},
computed: {
cellClass: function () {
return [
this.link ? 'kole-m-cell--link' : '',
this.borderless ? 'kole-m-cell--borderless' : '',
this.disabled ? 'is-disabled' : ''
].filter(Boolean);
}
}
};
</script>
<style src="./Cell.css"></style>
frameworks-mobile/Cell.vue3.vue · Vue 3 · 54 行
<template>
<button
v-if="link"
class="kole-m-cell"
:class="cellClass"
type="button"
:disabled="disabled"
@click="emit('click')"
>
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">{{ title }}</span>
<span v-if="desc" class="kole-m-cell__desc">{{ desc }}</span>
</span>
<slot>
<span v-if="value" class="kole-m-cell__value">{{ value }}</span>
</slot>
<span v-if="arrow" class="kole-m-cell__arrow" aria-hidden="true">›</span>
</button>
<div v-else class="kole-m-cell" :class="cellClass" :aria-disabled="disabled ? 'true' : null">
<span class="kole-m-cell__main">
<span class="kole-m-cell__title">{{ title }}</span>
<span v-if="desc" class="kole-m-cell__desc">{{ desc }}</span>
</span>
<slot>
<span v-if="value" class="kole-m-cell__value">{{ value }}</span>
</slot>
<span v-if="arrow" class="kole-m-cell__arrow" aria-hidden="true">›</span>
</div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
title: { type: String, default: '' },
desc: { type: String, default: '' },
value: { type: String, default: '' },
arrow: { type: Boolean, default: false },
link: { type: Boolean, default: false },
borderless: { type: Boolean, default: false },
disabled: { type: Boolean, default: false }
});
const emit = defineEmits(['click']);
const cellClass = computed(() => [
props.link ? 'kole-m-cell--link' : '',
props.borderless ? 'kole-m-cell--borderless' : '',
props.disabled ? 'is-disabled' : ''
].filter(Boolean));
</script>
<style src="./Cell.css"></style>
frameworks-mobile/Cell.uniapp.vue · uni-app(跨端:小程序 / App / H5) · 105 行
<template>
<view
class="kole-m-cell"
:class="cellClass"
:role="link ? 'button' : ''"
:aria-disabled="disabled ? 'true' : 'false'"
@tap="onTap"
>
<view class="kole-m-cell__main">
<text class="kole-m-cell__title">{{ title }}</text>
<text v-if="desc" class="kole-m-cell__desc">{{ desc }}</text>
</view>
<slot>
<text v-if="value" class="kole-m-cell__value">{{ value }}</text>
</slot>
<text v-if="arrow" class="kole-m-cell__arrow">›</text>
</view>
</template>
<script setup>
/* uni-app 端 · 单元格(移动端)— 规格 §7
跨端差异:用 view/text;可点单元格的语义靠 role="button"(小程序无 <button> 语义差异,
但 role 在 H5 产物里生效),点击用 @tap;尺寸用 rpx(88rpx = 44px @375pt)。 */
import { computed } from 'vue';
const props = defineProps({
title: { type: String, default: '' },
desc: { type: String, default: '' },
value: { type: String, default: '' },
arrow: { type: Boolean, default: false },
link: { type: Boolean, default: false },
borderless: { type: Boolean, default: false },
disabled: { type: Boolean, default: false }
});
const emit = defineEmits(['click']);
const cellClass = computed(() => [
props.link ? 'kole-m-cell--link' : '',
props.borderless ? 'kole-m-cell--borderless' : '',
props.disabled ? 'is-disabled' : ''
].filter(Boolean));
function onTap() {
if (!props.link || props.disabled) return;
emit('click');
}
</script>
<style>
.kole-m-cell {
--kole-m-action-height: 112rpx;
--kole-m-touch-target: 88rpx;
--kole-m-font-size-body: 32rpx;
--kole-m-font-size-label: 28rpx;
--kole-m-gutter: 32rpx;
display: flex;
align-items: center;
box-sizing: border-box;
width: 100%;
min-height: var(--kole-m-action-height);
padding: 24rpx var(--kole-m-gutter);
border-bottom: 1rpx solid var(--kole-color-border);
background-color: var(--kole-color-card-bg);
color: var(--kole-color-text-body);
font-size: var(--kole-m-font-size-body);
}
.kole-m-cell--borderless { border-bottom-color: transparent; }
.kole-m-cell--link:active { background-color: var(--kole-color-table-header-bg); }
.kole-m-cell.is-disabled { color: var(--kole-color-text-disabled); }
.kole-m-cell__main { flex: 1; display: flex; flex-direction: column; }
.kole-m-cell__title {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: var(--kole-color-text-title);
}
.kole-m-cell__desc {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: var(--kole-m-font-size-label);
color: var(--kole-color-text-secondary);
}
.kole-m-cell__value {
flex-shrink: 0;
max-width: 45%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: var(--kole-m-font-size-label);
color: var(--kole-color-text-secondary);
}
.kole-m-cell__arrow {
flex-shrink: 0;
padding-left: 8rpx;
color: var(--kole-color-text-placeholder);
}
</style>
测试与回归
断言在真实的 375×640 设备帧里跑(引擎与 PC 侧共用 tests/_runtime.js,触控行为动词来自移动端 tests/mobile/_behaviors.js)。
断言 17 条 · 全部通过 报告 2026-09-20 16:50:33
node site/dev-server.js &
REG_BASE=http://127.0.0.1:3311 node tools/run-mobile-regression.mjs # 全量 5 个组件
npm run verify:mobile-docs # 本页内容完整性 + API 与源码一致性
设计契约
components/cell.json(点击展开原始 JSON)
{
"schemaVersion": 1,
"sourceKind": "authored-spec",
"provenance": "authored-in-repo",
"specFile": "spec/移动端规格.md",
"confidence": "high",
"specSection": "7 · 单元格 Cell",
"slug": "cell",
"name": "单元格 Cell",
"semanticTypeCandidates": [
"cell",
"list-item"
],
"variantDimensions": [
{
"name": "arrow",
"values": [
"false",
"true"
]
},
{
"name": "link",
"values": [
"false",
"true"
]
}
],
"representativeVariants": [
{
"arrow": "true",
"link": "true",
"label": "可点单元格(带箭头)"
},
{
"arrow": "false",
"link": "false",
"label": "纯展示单元格"
},
{
"arrow": "false",
"link": "true",
"label": "可点无箭头"
},
{
"arrow": "true",
"link": "false",
"label": "有箭头但不可点"
}
],
"anatomy": {
"cell": "根元素,一行两类内容(左侧主区 / 右侧值区)",
"title": "主标题,单行省略",
"desc": "可选副标题,单行省略",
"value": "右侧值或状态文字",
"arrow": "可选右箭头,表示可进入",
"icon": "可选左侧图标"
},
"structurePatterns": {
"arrow": "false / true",
"link": "false(纯展示)/ true(整行可点)"
},
"usageHints": [
"列表的基本单元:一行里承载「标题 + 说明 + 值 + 箭头」,可整行点击进入下级",
"可点单元格整行都是热区,高度不小于 56px",
"按下反馈是整行背景变化,不是只有文字变色",
"单元格之间默认有 1px 分隔线,可用 borderless 关掉"
],
"doNotInvent": [
"多行标题的折叠规则",
"单元格内多列布局的栅格规则"
],
"unknowns": [
"副标题最多显示几行",
"右侧值超长时的截断策略"
],
"interaction": [
"可点单元格整行都是热区,高度不小于 56px",
"按下反馈是整行背景变化,不是只有文字变色",
"单元格之间默认有 1px 分隔线,可用 borderless 关掉"
],
"accessibility": [
"可点单元格用原生 button;纯展示单元格用 div",
"值区只作展示时不要放进可聚焦元素"
],
"api": {
"source": "implementation",
"note": "props / events / slots 为 6 端实现的公共接口(说明文字取自规格对应小节)。字段名与各端源码逐名核对:node tools/verify-mobile-docs.mjs",
"requiredNote": "「必传」按严格定义:实现里**没有默认值**时才为 Y(本门禁逐条核对 props 与各端源码的默认值,防止契约与实现脱节)。",
"props": [
{
"name": "title",
"type": "string",
"default": "''",
"desc": "主标题,单行省略(规格 §7.2)",
"required": false
},
{
"name": "desc",
"type": "string",
"default": "''",
"desc": "可选副标题,单行省略(规格 §7.2)",
"required": false
},
{
"name": "value",
"type": "string",
"default": "''",
"desc": "右侧值或状态文字(规格 §7.2)",
"required": false
},
{
"name": "arrow",
"type": "boolean",
"default": "false",
"desc": "变体 arrow:显示右箭头表示可进入(规格 §7.3)",
"required": false
},
{
"name": "link",
"type": "boolean",
"default": "false",
"desc": "变体 link:整行可点(规格 §7.3)",
"required": false
},
{
"name": "borderless",
"type": "boolean",
"default": "false",
"desc": "关掉底部 1px 分隔线(规格 §7.5)",
"required": false
},
{
"name": "disabled",
"type": "boolean",
"default": "false",
"desc": "置灰且不响应(规格 §7.4)",
"required": false
}
],
"events": [
{
"name": "click",
"params": "—",
"desc": "可点单元格(link=true)点击时触发"
}
],
"slots": [
{
"name": "default",
"desc": "右侧自定义内容,替代 value(规格 §7.2)"
},
{
"name": "icon",
"desc": "可选左侧图标(规格 §7.2)"
}
]
},
"variantClasses": {
"arrow": {
"false": [],
"true": [
".kole-m-cell__arrow"
]
},
"link": {
"false": [],
"true": [
".kole-m-cell--link"
]
}
},
"demos": [
{
"id": "basic",
"group": "01 组件类型",
"title": "基础用法",
"desc": "标题 + 右侧值 + 箭头,最常见的可点单元格。",
"variant": "link=true / arrow=true"
},
{
"id": "desc",
"group": "01 组件类型",
"title": "带副标题",
"desc": "两行文字(主 + 副),副标题单行省略。",
"variant": "desc"
},
{
"id": "custom",
"group": "01 组件类型",
"title": "自定义右侧",
"desc": "右侧放开关、标签等非文字内容(此处用标签示意)。",
"variant": "slots.default"
},
{
"id": "group",
"group": "02 组件状态",
"title": "分组列表",
"desc": "一组单元格共享分隔线;组内最后一条用 borderless 收尾。",
"variant": "borderless"
},
{
"id": "disabled",
"group": "02 组件状态",
"title": "禁用",
"desc": "置灰且不响应点击(无权限项的常见表达)。",
"variant": "disabled=true"
}
],
"related": [
{
"slug": "swipecell",
"why": "行内还需要滑动操作时用滑动单元格;只进入下级用普通单元格"
},
{
"slug": "actionsheet",
"why": "点击单元格后需要提供多个动作时用动作面板;单一跳转保留单元格语义"
}
]
}