Skip to content

插槽 Slot

默认插槽

这里以 button 为例子来说明 slot。

html
<o-button>我是按钮文本</o-button>
<o-button>我是按钮文本</o-button>

来看源码:

tsx
@tag('o-button')
export default class Button extends Component {
  ...
  ...
  ...
  
  render(props) {

    return <button disabled={props.disabled} {...extractClass(props, 'o-button', {
      ['o-button-' + props.type]: props.type,
      ['o-button-' + props.size]: props.size,
      'is-plain': props.plain,
      'is-round': props.round,
      'is-circle': props.circle,
      'is-disabled': props.disabled,
      'is-block': props.block
    })}>
      {props.text}
      <slot></slot>
    </button>
  }
}
@tag('o-button')
export default class Button extends Component {
  ...
  ...
  ...
  
  render(props) {

    return <button disabled={props.disabled} {...extractClass(props, 'o-button', {
      ['o-button-' + props.type]: props.type,
      ['o-button-' + props.size]: props.size,
      'is-plain': props.plain,
      'is-round': props.round,
      'is-circle': props.circle,
      'is-disabled': props.disabled,
      'is-block': props.block
    })}>
      {props.text}
      <slot></slot>
    </button>
  }
}

那么为什么有了插槽还需要 props.text? 这是由于如果在使用自定义标签之后再引入相关的 js,插槽内的内容会直接显示在页面当中,带来不好的用户体验,所以如果你不能提前引入自定义组件的 js,你可以使用下面的方式达到同样的效果且避免的以上问题:

html
<o-button text="我是按钮文本"></o-button>
<o-button text="我是按钮文本"></o-button>

具名插槽

具名插槽可以指定插入的位置:

html
<o-el>
  <span slot="abc"></span>
  <span slot="def"></span>
</o-el>
<o-el>
  <span slot="abc"></span>
  <span slot="def"></span>
</o-el>

对应的组件定义:

tsx
@tag('o-el')
export default class Button extends Component {
  
  render(props) {
    return <div>
      <slot name="abc"></slot>
      <div>Some Info</div>
      <slot name="def"></slot>
    </div>
  }
}
@tag('o-el')
export default class Button extends Component {
  
  render(props) {
    return <div>
      <slot name="abc"></slot>
      <div>Some Info</div>
      <slot name="def"></slot>
    </div>
  }
}

为 ShadowDOM 和 LightDOM 写样式

  • ShadowDOM
    • ::part() pseudo-element
    • :host-context selector
    • :host selector
    • :host selector and classes
    • CSS vars
  • LightDOM
    • ::slotted() pseudo-selector