Skip to content

自定义渲染

先用主题令牌、尺寸和 Resolver 调整外观;只有结构或业务内容需要变化时,再使用 Vue Slot、React Render Prop 或 Flutter Builder。这样能保留虚拟化、拖放、无障碍和边缘跳转协议。

跨端扩展面

区域VueReactFlutter
任务表task-* 表头、taskownerprogress SlotsrenderTaskHeaderrenderTaskrenderOwnerrenderProgressrowHeaderBuilder
任务条barbar-patternbar-effectrenderBartaskPatterntaskBarBuilder
依赖线dependency Slot 与 Path / Style / Effect ResolverrenderDependencyAlpha 1 使用主题色与内置几何
视口外入口edge-indicatorrenderEdgeIndicatoredgeIndicatorBuilder
空状态emptyrenderEmpty由宿主在空任务时组合
入场过渡viewportEnterEffect 与 CSSentryEffectentryTransitionBuilder

Vue Slots

vue
<YgGantt :tasks="tasks">
  <template #bar="{ task, progress }">
    <TaskBarContent :task="task" :progress="progress" />
  </template>

  <template #edge-indicator="{ side, task, jump }">
    <button type="button" :aria-label="`定位到 ${task.title}`" @click="jump">
      {{ side === 'left' ? '‹' : '›' }}
    </button>
  </template>
</YgGantt>

Vue 还提供 toolbar-extra、三列表头、完整依赖 SVG、纹理层和效果层。每个 Slot 的精确作用域见 Vue API

React Render Props

tsx
<YgGantt
  tasks={tasks}
  renderBar={({ task, progress }) => (
    <TaskBarContent task={task} progress={progress} />
  )}
  renderEdgeIndicator={({ side, task, jump }) => (
    <button aria-label={`定位到 ${task.title}`} onClick={jump}>
      {side === 'left' ? '‹' : '›'}
    </button>
  )}
/>

Render Prop 应返回轻量节点。不要为每个可见任务重复创建大型图表、滤镜或持续布局动画。

Flutter Builders

dart
YotsubaGantt(
  tasks: tasks,
  taskBarBuilder: (context, details) {
    return TaskBarContent(task: details.task, selected: details.selected);
  },
  edgeIndicatorBuilder: (context, details) {
    return IconButton(
      tooltip: '定位到 ${details.task.title}',
      onPressed: details.jump,
      icon: Icon(details.side == YgEdgeSide.left
          ? Icons.chevron_left
          : Icons.chevron_right),
    );
  },
)

性能边界

  • 自定义渲染只会为虚拟窗口内的任务执行,但单个节点成本仍由宿主承担。
  • 图片纹理应复用缓存资源;避免为每条任务解码独立大图。
  • 进入视口的过渡只使用 opacitytransform,持续效果应限制在选中或少量任务。
  • 边缘入口必须保留 jump(),依赖线编辑必须保留 edit(),否则会丢失内置交互。

MIT License · Vue / React / Flutter