wip限制不能只靠css实现,因为html无状态拦截能力,必须在dragover/drop事件中用js实时统计目标列的有效任务数并调用preventdefault()阻止超限拖入。

WIP限制为什么不能只靠CSS实现
HTML本身不提供WIP(在制品)计数或状态拦截能力,单纯用<div>加CSS样式只能“显示”数字,无法阻止用户拖入超限任务。真正起作用的是交互逻辑层——你得在拖拽开始/放置时检查目标列的当前任务数,并主动拒绝非法操作。
<ul>
<li>常见错误:把<code>wip-limit="3"写成自定义属性就以为生效了,但没绑定JS监听,拖10个进去也毫无反应
dragover和drop事件里调用event.preventDefault()来取消默认行为<li>标签数量用原生JS实现拖拽拦截的最小可行代码
不需要框架也能做,重点是拿到目标列元素后,立刻查它内部“正在处理”的任务数(比如带data-status="in-progress"的项),再比对data-wip-limit值:
document.addEventListener('dragover', (e) => {
const target = e.target.closest('[data-wip-limit]');
if (!target) return;
const limit = parseInt(target.dataset.wipLimit, 10);
const current = target.querySelectorAll('[data-status="in-progress"]').length;
if (current >= limit) {
e.preventDefault(); // 关键:禁用放置
target.classList.add('wip-overflow'); // 可选视觉反馈
}
});
-
data-wip-limit必须是数字,字符串如"3"要转parseInt - 别漏掉
e.preventDefault(),否则拖拽始终允许,限制形同虚设 - 视觉反馈建议用
dragenter/dragleave补全,避免用户反复试错
Vue/React里WIP限制容易漏掉的响应时机
框架组件更新是异步的,直接在drop事件里读ref或state可能拿到旧数据。例如Vue中任务列表用v-for渲染,拖入新任务后tasks.length还没更新,导致误判“未超限”。
- Vue:在
nextTick里检查计数,或用watch监听数组变化后再校验 - React:不要在
onDrop里直接读tasks.length,改用useEffect响应更新后的状态 - 通用原则:WIP校验必须发生在DOM真实更新之后,而不是状态更新那一刻
显示WIP剩余数时要注意动态刷新
很多人只在页面加载时算一次3 / 5这样的提示,但用户移走任务后数字卡住不动,体验断裂。显示逻辑必须和任务移动强同步。
- 推荐在每次
drop和dragend后,重新计算并更新data-wip-remaining属性或旁注文本 - 避免用
innerText硬写,改用dataset.wipRemaining = String(remain)保持语义清晰 - 如果列支持多状态(如“待办”“进行中”“测试中”),WIP限制通常只约束“进行中”,别把所有
li都算进去











