TSone

核心概念

本文档介绍 TSone 框架的核心概念,帮助您更好地理解框架的设计理念和工作原理。

1. 应用实例

应用实例是 TSone 应用的入口点,通过 createApp 创建。

import { createApp } from '@geektech/tsone';

const app = createApp({
  state: {
    appName: 'My App',
  },
});

app.mount();

2. 组件

所有组件都继承 Component<Props, State>,通过 protected render(): VNode 描述 UI。

组件生命周期

  • beforeMount(): 组件挂载前调用
  • onMounted(): 组件挂载后调用
  • beforeUpdate(): 组件更新前调用
  • onUpdated(): 组件更新后调用
  • beforeUnmount(): 组件卸载前调用
  • onUnmounted(): 组件卸载后调用

组件渲染

组件通过 render() 返回虚拟节点,渲染器会根据 VNode 类型选择文本、元素、组件或插槽策略。

3. 响应式系统

TSone 的响应式系统基于 Proxy 实现,常用 API 包括 reactive、effect、computed、readonly、ref 和 stop。

核心 API

  • reactive(target): 创建响应式对象
  • effect(fn): 创建副作用函数
  • computed(fn): 创建计算属性
  • readonly(target): 创建只读响应式对象
  • ref(value): 创建包装单值的响应式引用

4. 虚拟 DOM

虚拟 DOM 是对真实 DOM 的轻量级抽象。

虚拟 DOM 结构

const vnode = {
  tag: 'div',
  props: { className: 'container' },
  listeners: {
    click: () => console.log('clicked'),
  },
  children: [
    'Hello World',
    { tag: 'button', children: ['Click Me'] },
  ],
};

const componentVnode = {
  component: MyComponent,
  props: { title: 'My Component' },
};

5. 路由系统

通过 createRouter 创建路由实例,并使用 RouterView 与 RouterLink 参与渲染和导航。

路由配置

import { createRouter } from '@geektech/tsone/router';

const router = createRouter({
  routes: [
    { path: '/', component: HomeComponent, meta: { title: '首页' } },
    { path: '/about', component: AboutComponent, meta: { title: '关于我们' } },
  ],
  mode: 'history',
  base: '/',
});

6. 样式管理

TSone 提供内置 StyleManager,每个组件实例都可以通过 this.styleManager 管理样式。

样式定义

protected initStyles() {
  this.styleManager.addStyle('.container', {
    selector: '.container',
    properties: {
      width: '100%',
      maxWidth: '1200px',
      margin: '0 auto',
    },
  });
}

7. 插件系统

插件通过 app.use() 安装,可向应用上下文和组件扩展能力。

插件示例

const myPlugin = {
  install(app: { myMethod?: () => void }) {
    app.myMethod = () => {
      console.log('My plugin method');
    };
  },
};

app.use(myPlugin);

8. 事件系统

组件可以通过 emit/on 进行事件通知,on 返回取消订阅函数。

事件示例

this.emit('custom-event', 'event data');

const unsubscribe = component.on('custom-event', (data) => {
  console.log('Event received:', data);
});
unsubscribe();

9. 条件、列表、依赖与表单

VNode 的 directions.if 控制元素、组件和插槽的挂载;each 为列表提供稳定 key。

const rows = each(
  this.state.rows,
  (row) => ({ tag: 'li', children: [row.name] }),
  (row) => row.id
);

const sidebar = {
  component: Sidebar,
  directions: { if: this.state.open },
};

应用或组件可通过 provide 提供依赖,子组件用 inject 获取最近的值。

const LOCALE: InjectionKey<string> = Symbol('locale');
app.provide(LOCALE, 'zh-CN');
const locale = this.inject(LOCALE, 'en-US');

原生表单节点通过 directions.model 绑定状态,校验由独立的 createForm 控制器完成。

const name = Input({ directions: { model: 'profile.name' } });
const form = createForm(this.state, {
  'profile.name': [required('请输入姓名'), minLength(2)],
});
const result = form.validate();

总结

先阅读 架构总览 从整体上理解各层关系;以上概念共同组成 TSone 的应用模型,继续阅读 组件系统、响应式系统 与 路由系统 可以看到更具体的代码模式。