TSone

样式管理

TSone 提供了内置的样式管理系统,通过 StyleManager 类管理组件样式。

核心概念

StyleManager

每个组件实例都有 styleManager,可用于添加、修改和删除样式。

tsone build 和 dev 自动将 document.styles 和固定 initStyles / 新建 StyleManager 的初始化规则输出为静态 CSS,无需改写字面量或局部、模块数组的 forEach。纯主题表达式可分析,props/state、未知调用或可见修改保留运行时路径。组件同步内联样式在匹配外链加载后切换;动态修改恢复原位置,卸载清理实例节点。styleElement 在外链激活时为 null,规则对象仍在 bundle 中,首次初始化仍序列化。相对或片段 URL、@import、不明确地址和 base 元素回退;dev CSS 使用当前构建版本的资源 URL;watch 成功后一起替换脚本和 CSS,失败保留上一版,非 watch dev 保留各次构建资源;library 保持原流程。模块发现增加构建步骤,不承诺更快 build。

样式对象

  • selector: CSS 选择器
  • properties: CSS 属性和值的映射

基本使用

在组件中使用

import { Component, VNode } from '@geektech/tsone';

class ButtonComponent extends Component<object, object> {
  protected initState() {
    return {};
  }

  protected initStyles() {
    this.styleManager.addStyle('.button', {
      selector: '.button',
      properties: {
        padding: '8px 16px',
        backgroundColor: '#007bff',
        color: '#fff',
        borderRadius: '4px',
      },
    });

    this.styleManager.addStyle('.button:hover', {
      selector: '.button:hover',
      properties: { backgroundColor: '#0069d9' },
    });
  }

  protected render(): VNode {
    return {
      tag: 'button',
      props: { className: 'button' },
      children: ['Click Me'],
    };
  }
}

样式管理 API

添加样式

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

移除样式

this.styleManager.removeStyle('.container');

清除所有样式

this.styleManager.clearStyles();

获取样式

const buttonStyle = this.styleManager.getStyle('.button');
console.log(buttonStyle);

高级用法

样式优先级

  • 更具体的选择器拥有更高优先级
  • 相同特异性下,后添加的规则会覆盖先添加的规则

响应式样式

this.styleManager.addStyle('@media (max-width: 768px)', {
  selector: '@media (max-width: 768px)',
  properties: {
    '.container': { padding: '10px' },
  },
});

动态样式

class DynamicStyleComponent extends Component<object, { isActive: boolean }> {
  protected initState() {
    return { isActive: false };
  }

  protected initStyles() {
    this.styleManager.addStyle('.box.active', {
      selector: '.box.active',
      properties: { backgroundColor: '#007bff' },
    });
  }

  protected render(): VNode {
    return {
      tag: 'div',
      props: {
        className: `box ${this.state.isActive ? 'active' : ''}`,
      },
      listeners: {
        click: () => {
          this.state.isActive = !this.state.isActive;
        },
      },
      children: ['Click to toggle'],
    };
  }
}

全局样式

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

const app = createApp();

app.styleManager.addStyle('body', {
  selector: 'body',
  properties: {
    fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
    fontSize: '16px',
    lineHeight: '1.5',
  },
});

样式管理原理

样式注入

  • 创建 style 元素
  • 将样式规则转换为 CSS 字符串
  • 把 CSS 写入 style 元素
  • 将 style 元素注入到文档头部

样式更新

  • 更新内部样式存储
  • 重新生成 CSS 字符串
  • 刷新 style 元素内容

最佳实践

样式组织

  • 每个组件优先管理自己的样式
  • 使用语义化类名
  • 把相关规则组织在一起

性能优化

  • 尽量在 initStyles() 中一次性添加样式
  • 减少运行时频繁添加和删除样式
  • 避免过于复杂的选择器

常见问题

  • 样式不生效:检查选择器和覆盖关系
  • 样式冲突:提高选择器特异性或增加命名空间
  • 动态样式性能:高频变化场景可考虑 CSS 变量

总结

StyleManager 提供了轻量、可组合的组件样式管理方式,既适合局部样式,也能承载应用级全局样式。