指南
安装
每个框架一个包——版本要求、第一次渲染、主题启动和 SSR 配置。
#环境要求
| 你的框架 | 版本要求 | 安装 |
|---|---|---|
| Vue | vue ^3.5 | @bysages/vue |
| React | react、react-dom >=18 | @bysages/react |
| Solid | solid-js ^1.9 | @bysages/solid |
| Svelte | svelte ^5 | @bysages/svelte |
框架本身是唯一的对等依赖,其余都会作为普通依赖自动装好:无头交互层(@ark-ui/*、@zag-js/*)、数据表格栈(@tanstack/*)、图标注册表(@bysages/icons)、样式和令牌层(@bysages/core → @bysages/tokens)。所有包都是 ESM,带完整的 TypeScript 类型。
pnpm add @bysages/vue # 或 @bysages/react / @bysages/solid / @bysages/svelte
两个可选包按需安装,同样只要求你的框架:
pnpm add @bysages/charts # 图表,按框架入口引入:"@bysages/charts/vue" 等
pnpm add @bysages/workflow # 工作流图协议和 X6 画布
@bysages/core 随任意包装自动装上,但它是对外 API——自己控制主题时,直接从它 import applyTheme。
#第一次渲染
样式不需要 import:每个组件在第一次使用时自动注入自己的样式。
<script setup lang="ts">
import { Button } from "@bysages/vue";
</script>
<template>
<Button variant="solid" tone="ink">发布</Button>
</template>
import { Button } from "@bysages/react";
export function Page() {
return <Button variant="solid" tone="ink">发布</Button>;
}
import { Button } from "@bysages/solid";
export function Page() {
return <Button variant="solid" tone="ink">发布</Button>;
}
<script lang="ts">
import { Button } from "@bysages/svelte";
</script>
<Button variant="solid" tone="ink">发布</Button>
四个包装导出同样的组件名和 props,换框架只需要换一条 import 路径。
#启动主题
不调用任何函数时,主题默认 mode: "system",其他维度都是 "auto"。要让主题在刷新后保留、跟随系统明暗:
import { applyTheme, initTheme, getTheme } from "@bysages/core";
initTheme(); // 从 localStorage 恢复,并跟随系统
const theme = applyTheme({ // 设置并保存,返回完整的 Theme
mode: "dark",
accent: "celadon",
scene: "studio",
});
getTheme(); // 读取当前主题
initTheme()读取 localStorage 的bs-theme键并恢复;mode为"system"时监听prefers-color-scheme,系统切换明暗时跟着切。applyTheme(partial)与当前主题合并,写入根元素属性,并保存到 localStorage;传persist: false可以不保存。"auto"的值在调用时解析:accent 和 contrast 跟随场景的默认搭配,mode: "system"跟随系统。
各维度的完整取值见主题。
#样式的三种供法
- 默认:运行时注入。 组件首次使用时按族注入样式,令牌经
injectTokens()进来,零配置。 - 手动内联令牌 CSS。
@bysages/core导出的tokensCss是整份令牌加基础样式的字符串。SSR 或严格 CSP 环境下,把它内联进 head:import { tokensCss } from "@bysages/core"; // Nuxt: useHead({ style: [{ innerHTML: tokensCss }] }) - 构建期 import。 同一份样式作为文件引入,交给会收集 CSS 的打包器:
import "@bysages/tokens/css";
无论哪种方式,组件样式都在运行时注入,变的只是令牌层。
#服务端渲染
有两件事服务器做不了,各有解法:
- 令牌 CSS 的注入。 让初始 HTML 直接带上令牌:把
tokensCss塞进 head(上面的第 2 种方式),否则首屏没有样式,会闪一下。 - 浮层。 对话框、气泡、下拉、工具提示会在客户端把弹层挂到
document.body。在预渲染框架里,把它们包进 client-only 边界:Vue 的<ClientOnly>、React 的next/dynamic(ssr: false)、Solid 的<ClientOnly>、Svelte 的onMount判断,保证服务端输出和水合后的结果一致。