You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在StencilJS中根据动态数组设置div的宽度与背景色?

解决StencilJS动态生成带样式的div元素问题

核心要点说明

StencilJS中style属性支持两种合法写法:对象形式(推荐,类型安全) 或 模板字符串形式;同时生成JSX元素列表时必须用Array.map()替代forEach()——因为forEach()仅做遍历,不会返回可被渲染的元素数组。另外,建议不要直接修改原数组元素,而是在映射时生成处理后的新对象,避免产生副作用。

完整实现代码

import { Component, State } from '@stencil/core';

@Component({
  tag: 'dynamic-bars',
  styleUrl: 'dynamic-bars.css',
})
export class DynamicBars {
  // 预设的备用颜色池
  private colors = ['#2c8646', '#69c0f9', '#f9a826', '#f44336'];
  // 颜色循环索引
  @State() private colorIndex = 0;
  // 动态数据数组(可替换为@Prop接收父组件传值)
  @State() private objArray = [
    { color: '#2c8646', value: 30 },
    { color: '#69c0f9', value: 50 },
    { value: 0 }, // 测试无颜色、值为0的场景
    { tooltip: '自定义提示' }, // 测试无颜色、无值的场景
  ];

  // 统一处理单个数据项的默认值
  private processItem(item: any) {
    // 处理颜色默认值,循环取用预设颜色
    const color = item.color?.trim() || this.colors[this.colorIndex];
    this.colorIndex = (this.colorIndex + 1) % this.colors.length;
    
    // 处理宽度值默认值
    const value = item.value || 100;
    
    // 处理tooltip默认值
    const tooltip = item.tooltip || '';

    return { color, value, tooltip };
  }

  render() {
    return (
      <div class="bars-container">
        {/* 使用map生成JSX元素列表,必须添加唯一key */}
        {this.objArray.map((item, index) => {
          const processedItem = this.processItem(item);
          
          // 写法1:对象形式style(推荐,TS类型检查友好)
          const barStyle = {
            width: `${processedItem.value}%`, // 务必带上单位,如%/px
            backgroundColor: processedItem.color,
          };

          return (
            <div
              key={index} // 优先用数据唯一ID当key,此处用索引做示例
              class="bar-item"
              style={barStyle}
              title={processedItem.tooltip}
            />
          );

          // 写法2:模板字符串形式style
          // return (
          //   <div
          //     key={index}
          //     class="bar-item"
          //     style={`width: ${processedItem.value}%; background-color: ${processedItem.color};`}
          //     title={processedItem.tooltip}
          //   />
          // );
        })}
      </div>
    );
  }
}

关键细节解释

  1. 使用map生成元素列表:forEach()仅执行遍历逻辑,不会返回新数组,无法被Stencil的render方法识别渲染;map()会返回处理后的JSX元素数组,是生成动态列表的标准方式。
  2. style属性的正确用法:
    • 对象形式:CSS属性名采用驼峰式(如backgroundColor而非background-color),值为带单位的字符串,Stencil会自动转换为合法行内样式。
    • 模板字符串形式:需保留CSS原生属性名格式(短横线分隔),同时确保值的格式正确(必须带单位)。
  3. 避免修改原数组:通过processItem方法生成新的处理后对象,保持原数组纯净——尤其当objArray是父组件传入的@Prop时,直接修改会引发不可预期的状态问题。
  4. key属性的必要性:生成列表元素时必须添加唯一key,帮助Stencil优化DOM更新性能;优先使用数据自身的唯一ID,无ID时可临时用索引(不推荐频繁排序的列表)。
  5. 状态驱动更新:colorIndex用@State装饰,确保索引变化时组件自动重新渲染,实现颜色的循环分配。

内容的提问来源于stack exchange,提问作者SamGS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:53:11