文档中心

探索 DWeb 框架的无限可能,构建下一代高性能 Web 应用

客户端 API

DWeb 框架提供了丰富的客户端 API,用于在浏览器环境中进行状态管理、主题切换、国际化、路由导航等操作。所有客户端 API 都从 `@dreamer/dweb/client` 模块导出。

**注意:**所有客户端 API 在服务端环境中会返回 `null` 或执行空操作,这是正常行为。

快速开始

在组件中导入并使用客户端 API:

Code
import { 
  route, 
  routeTo,
  goBack,
  getCurrentPath, 
  useThemeStore,
  translate,
  useStore 
} from "@dreamer/dweb/client";
import { counterStore } from "../stores/counter.ts";

// 在组件中使用
export default function MyPage() {
  const theme = useThemeStore();
  const counter = useStore(counterStore);
  
  const handleNavigate = () => {
    routeTo({ path: "/docs", params: { page: 1 } });
  };
  
  const handleGoBack = () => {
    goBack();
  };
  
  return (
    <div>
      <h1>{translate("page.title")}</h1>
      <p>当前主题: {theme.value}</p>
      <p>计数: {counter.count}</p>
      <button onClick={handleNavigate}>跳转</button>
      <button onClick={handleGoBack}>返回</button>
    </div>
  );
}

Store 状态管理

DWeb 框架提供了完整的状态管理解决方案,支持全局状态管理和响应式更新。

基本 API

Code
import { 
  getStore, 
  getStoreState, 
  setStoreState,
  subscribeStore,
  useStore 
} from "@dreamer/dweb/client";
import { counterStore } from "../stores/counter.ts";

// 获取 Store 实例
const store = getStore();

// 获取状态
const state = getStoreState<AppState>();

// 更新状态
setStoreState({ count: 10 });
setStoreState((prev) => ({ ...prev, count: prev.count + 1 }));

// 订阅状态变化
const unsubscribe = subscribeStore((state) => {
  console.log("状态已更新:", state);
});

// 在组件中使用(响应式)
const counter = useStore(counterStore);
console.log(counter.count);

defineStore - 声明式定义 Store

使用 defineStore 可以声明式地定义 Store,支持 Options API 和 Setup API 两种方式。

Code
import { defineStore } from "@dreamer/dweb/client";

// 定义 Store
export const counterStore = defineStore("counter", {
  state: () => ({
    count: 0,
    message: "",
  }),
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
  },
});

// 使用
counterStore.increment();
console.log(counterStore.count);

// 在组件中使用(响应式)
import { useStore } from "@dreamer/dweb/client";
const counter = useStore(counterStore);

主题管理

DWeb 框架内置了主题切换功能,支持浅色、深色和自动(跟随系统)三种模式。

Code
import { 
  getTheme, 
  setTheme, 
  toggleTheme,
  useThemeStore,
  subscribeTheme 
} from "@dreamer/dweb/client";

// 获取当前主题
const theme = getTheme(); // 'light' | 'dark' | 'auto'

// 设置主题
setTheme("dark");

// 切换主题
toggleTheme();

// 在组件中使用(响应式)
const theme = useThemeStore();
console.log(theme.value); // 'light' | 'dark'
console.log(theme.mode); // 'light' | 'dark' | 'auto'

// 订阅主题变化
subscribeTheme((theme) => {
  console.log("主题已切换为:", theme);
});

国际化 (i18n)

DWeb 框架提供了完整的国际化支持,支持多语言切换和动态翻译。

Code
import { 
  translate, 
  getCurrentLanguage,
  setCurrentLanguage 
} from "@dreamer/dweb/client";

// 翻译文本
const title = translate("common.title");
const welcome = translate("common.welcome", { name: "John" });

// 获取当前语言
const lang = getCurrentLanguage(); // 'zh-CN' | 'en-US'

// 切换语言
await setCurrentLanguage("en-US");

路由工具

DWeb 框架提供了路由导航工具函数,支持 SPA 无刷新导航和参数传递。

Code
import { 
  route, 
  routeTo,
  goBack,
  getCurrentPath, 
  getQueryParams,
  getCurrentUrl 
} from "@dreamer/dweb/client";

// 基本导航
route("/docs");

// routeTo 是 route 的别名,功能完全相同
routeTo("/docs");

// 带查询参数(字符串形式)
route("/docs?page=1&sort=name");

// 使用对象形式传递参数
route({ 
  path: "/docs", 
  params: { page: 1, sort: "name" } 
});

// 替换当前历史记录
route("/docs", true);

// 返回上一页
goBack();

// 返回上两页
goBack(2);

// 前进一页(如果历史记录中有)
goBack(-1);

// 获取当前路径
const path = getCurrentPath(); // '/docs'

// 获取查询参数
const params = getQueryParams(); // { page: "1", sort: "name" }

// 获取完整 URL
const url = getCurrentUrl(); // 'https://example.com/docs?page=1'

React/Preact 组件示例

在 Preact/React 组件中使用客户端 API 的完整示例:

Code
import { useEffect, useState } from 'preact/hooks';
import { 
  route, 
  routeTo,
  goBack,
  getCurrentPath,
  useThemeStore,
  translate,
  useStore 
} from '@dreamer/dweb/client';
import { counterStore } from '../stores/counter.ts';

export default function ExamplePage() {
  const theme = useThemeStore();
  const counter = useStore(counterStore);
  const [currentPath, setCurrentPath] = useState('');

  useEffect(() => {
    setCurrentPath(getCurrentPath());
  }, []);

  const handleNavigate = () => {
    routeTo({ path: '/docs', params: { page: 1 } });
  };

  const handleGoBack = () => {
    goBack();
  };

  return (
    <div>
      <h1>{translate('page.title')}</h1>
      <p>当前主题: {theme.value}</p>
      <p>当前路径: {currentPath}</p>
      <p>计数: {counter.count}</p>
      <button onClick={handleNavigate}>跳转到文档</button>
      <button onClick={handleGoBack}>返回上一页</button>
      <button onClick={() => counter.increment()}>增加计数</button>
    </div>
  );
}

API 参考

Code
// ===== 通用常量 =====
const IS_CLIENT: boolean
const IS_SERVER: boolean

// ===== Store 状态管理 =====
function getStore(): Store | null
function getStoreState<T>(): T | null
function setStoreState<T>(updater: Partial<T> | ((prev: T) => Partial<T>)): void
function subscribeStore<T>(listener: (state: T) => void): (() => void) | null
function resetStore(): void
function defineStore<T>(name: string, options: StoreOptions<T>): StoreInstance<T> & T
function useStore<T>(store: StoreInstance<T>): StoreInstance<T> & T

// ===== 主题管理 =====
function getTheme(): 'light' | 'dark' | 'auto' | null
function getActualTheme(): 'light' | 'dark' | null
function setTheme(theme: 'light' | 'dark' | 'auto'): void
function toggleTheme(): 'dark' | 'light' | null
function switchTheme(theme: 'light' | 'dark' | 'auto'): 'light' | 'dark' | 'auto' | null
function subscribeTheme(listener: (theme: 'light' | 'dark') => void): (() => void) | null
function useThemeStore(): ThemeStoreInstance & ThemeStoreState

// ===== 国际化 (i18n) =====
function translate(key: string, params?: Record<string, any>): string
function getCurrentLanguage(): string | null
function setCurrentLanguage(langCode: string): Promise<void>
function getTranslations(): Record<string, unknown> | null
function isI18nInitialized(): boolean

// ===== 路由工具 =====
function route(
  path: string | { path: string; params?: Record<string, string | number | boolean> },
  replace?: boolean
): boolean
function routeTo(
  path: string | { path: string; params?: Record<string, string | number | boolean> },
  replace?: boolean
): boolean
function goBack(steps?: number): boolean
function getCurrentPath(): string
function getQueryParams(): Record<string, string>
function getCurrentUrl(): string

注意事项

  1. 客户端环境检查:所有客户端 API 在服务端环境中会返回 null 或执行空操作,这是正常行为。
  2. 类型安全:使用 TypeScript 时,建议为 Store 状态定义明确的类型,以获得更好的类型提示。
  3. 响应式更新:使用 useStoreuseThemeStore Hook 时,状态变化会自动触发组件重新渲染。
  4. 路由导航routerouteTo 函数优先使用框架的 SPA 导航,如果不可用会回退到整页跳转。goBack 函数使用浏览器的历史记录 API 返回上一页。
  5. i18n 初始化:使用 i18n 相关 API 前,确保 i18n 插件已正确初始化。

相关文档