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

如何在Stencil.js中通过插槽将Props从父组件传给子组件?

解决Stencil组件的插槽Props传递与代码优化问题

一、插槽Props传递问题的解决

你原代码中<slot {...this.props()}/>的写法无效,因为Stencil的插槽本身不会将属性传递给插槽内的子组件。要实现父组件向插槽子组件传递props(包括函数),推荐使用Context API,这是跨组件传递数据的标准方案:

步骤1:父组件创建并提供Context

import { Component, h, Prop, createContext, Provider } from '@stencil/core';

// 定义Context的类型
interface ParentContext {
  textColor: string;
  fontFamily: string;
  // 如果需要传递函数,在这里定义类型,比如:
  // handleSomeAction: () => void;
}

// 创建Context,设置默认值
const ParentContext = createContext<ParentContext>({
  textColor: '',
  fontFamily: ''
});

@Component({
  tag: 'my-parent',
  shadow: true,
})
export class MyParent {
  @Prop() textColor: string = '';
  @Prop() fontFamily: string = '';
  // 补上原代码遗漏的fontWeight Prop
  @Prop() fontWeight: string = '';

  // 合并原有的两个函数,生成样式和传递用的props
  getCombinedData() {
    return {
      // 本地div使用的样式
      localStyles: {
        color: this.textColor,
        fontFamily: this.fontFamily
      },
      // 用于Context传递的props
      contextProps: {
        textColor: this.textColor,
        fontFamily: this.fontFamily,
        fontWeight: this.fontWeight
      }
    };
  }

  render() {
    const { localStyles, contextProps } = this.getCombinedData();

    return (
      <Host>
        <div class="some-content" style={localStyles}></div>
        {/* 用Provider包裹插槽,将props注入Context */}
        <Provider context={ParentContext} value={contextProps}>
          <slot />
        </Provider>
      </Host>
    );
  }
}

步骤2:子组件消费Context

import { Component, h, Prop, Consumer } from '@stencil/core';
// 导入父组件定义的Context(建议抽离到单独文件复用)
import { ParentContext } from './my-parent';

@Component({
  tag: 'my-child',
  shadow: true,
})
export class MyChild {
  // 保留Prop作为降级方案,优先使用Context的值
  @Prop() textColor: string = '';
  @Prop() fontFamily: string = '';

  render() {
    return (
      {/* 用Consumer获取Context中的数据 */}
      <Consumer context={ParentContext}>
        {(context) => {
          // 合并Context和自身Prop,优先取Context的值
          const finalTextColor = context.textColor || this.textColor;
          const finalFontFamily = context.fontFamily || this.fontFamily;

          return (
            <Host style={{ color: finalTextColor, fontFamily: finalFontFamily }}>
              <slot />
            </Host>
          );
        }}
      </Consumer>
    );
  }
}

如果需要传递函数,只需在Context的类型定义中添加函数类型,在父组件中实现函数并放入contextProps,子组件消费后即可调用。

二、代码优化:合并两个函数

原代码中的getAccordionProps和props函数逻辑重复,都是基于父组件的Props生成不同结构的对象。上面的代码已经将它们合并为getCombinedData函数,一次性返回本地样式和传递用的props,减少了重复代码,逻辑更清晰。

另外注意原代码中的几个小问题:

  • 父组件props()函数中使用了fontWeight,但未定义对应的@Prop(),需要补上;
  • 子组件中调用了getAccordionProps()但未实现,已在优化后的代码中直接处理样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:20:32