自定义 Header 布局 - 斯巴达克斯店面

Custom Header Layout - Spartacus Storefront

有没有人解决或知道如何解决斯巴达克斯中 header 的以下情况?

我想在 header 中显示一个布局,在两个级别块的右侧,在一个级别块的左侧。

Objective Header Layout

考虑到 header 的 Spartacus 实现,我想不出该怎么做,因为我看不到如何包装某些插槽。 考虑到 Spartacus 中 header 的实现,在 StorefrontComponent 内部我无法使用 ConfigModule.withConfig ({...}, as CmsConfig)

替换它

我知道并已经尝试过我可以替换 header,实现一个 Outlet (cxOutletRef = "header"),但这使得无法通过 SmartEdit 对其进行编辑,这对我来说是无法接受的。

有什么建议吗?或者可能的解决方案?

作为最后一个选择,我想到我可以从后面创建一个组件类型,并使用 "ConfigModule.withConfig ({...}, as CmsConfig)" 实现“冲突 two-level”块从 Angular 映射它从头开始,甚至整​​个 header.

谢谢!

////// 更正 09/23/20 //////

插座不会阻止通过 SmartEdit 进行编辑。需要指明组件对应的Slot,使用PageSlotComponent很容易实现。

✔ 示例:

<ng-template cxOutletRef="cx-header">
      <header
        cxSkipLink="cx-header"
        [cxFocus]="{ disableMouseFocus: true }"
        [class.is-expanded]="isExpanded$ | async"
        (keydown.escape)="collapseMenu()"
        (click)="collapseMenuIfClickOutside($event)"
      >
        <cx-page-slot position="MiniCart"></cx-page-slot>
      </header>
      <cx-page-slot position="BottomHeaderSlot"> </cx-page-slot>
      <cx-global-message></cx-global-message>
    </ng-template>

通过这种方式,SmartEdit 确实允许您在相应的插槽中编辑 MiniCart 组件。

错误方式:

<ng-template cxOutletRef="cx-header">
  <header
    cxSkipLink="cx-header"
    [cxFocus]="{ disableMouseFocus: true }"
    [class.is-expanded]="isExpanded$ | async"
    (keydown.escape)="collapseMenu()"
    (click)="collapseMenuIfClickOutside($event)"
  >
    <cx-mini-cart></cx-mini-cart>
  </header>
  <cx-page-slot position="BottomHeaderSlot"> </cx-page-slot>
  <cx-global-message></cx-global-message>
</ng-template>

我对斯巴达克斯不是很有经验,所以这可能不是正确的方法。只是想和你一起思考这个问题。

我认为您可以扩展布局配置并使用 CSSGrid 设置插槽样式。因此,例如您的布局可能是这样的:

  layoutSlots: {
    header: {
      lg: {
        slots: [
          'SiteLinks',
          'SiteLogin',
          'HeaderLinks',
          'SiteLogo',
          'NavigationBar',
          'SearchBox',
          'MiniCart',
          'NavigationBar2',
        ],
      },
      slots: ... (for mobile view)
    },
  },

并为插槽的位置创建自定义 css 网格。

如果您想拥有更多标记控制,您可以使用 cxOutletRef 将 header 替换为类似以下内容:

<ng-template cxOutletRef="cx-header">
  <header>
    <div class="header-top">
      <cx-page-layout section="headerTop"></cx-page-layout>
    </div>

    <div class="header-bottom">
      <cx-page-layout section="headerBottom"></cx-page-layout>
    </div>
  </header>
</ng-template>

然后在您的配置中划分 headerTop 和 headerBottom 之间的插槽。

您确实可以通过自定义布局配置和附加 CSS 来解决此问题,但这不是必需的。我给你几个选项供你考虑:

选项1:更改生成的DOM

您可以按照@pwavg 的建议提供自定义布局配置,甚至可以引入自定义店面组件。 如果您引入自定义布局配置,您将受到我们在店面组件中使用的部分的限制。如果您坚持自定义部分(即包装搜索框、登录、mincart 和导航的元素),则需要引入自定义店面组件。这里的缺点是您将偏离标准的 Spartacus 组件,这可能会导致将来缺少功能。

选项 2:纯 CSS

纯 CSS 解决方案是最简单的。您不需要更改任何实际 DOM,但将一些自定义 CSS 规则应用于标准 DOM。网格系统确实是为此而设计的。开始有点复杂,但可以完成工作。 您实际上也可以使用 flexbox 实现此目的,但您需要将徽标插槽移出 flexbox 流。

这是一个实际的快速而肮脏的代码片段,用于演示仅通过一些 CSS 规则进行更改。它带有一些 assumptions/limitations,但在大多数情况下它可能没问题。


header {
  cx-page-slot.SiteLogo {
    // we absolute position the logo, so it flows outside the flexbox system. this requires
    // an hard-coded top position, that might be fine, but I don't know the details. 
    position: absolute;
    top: 60px;
  }

  cx-page-slot.SearchBox {
    // align searchbox to the left, not sure if that's required, but looks better
    margin: 14px auto 14px 150px;
  }

  cx-page-slot.NavigationBar {
    margin-left: 150px;
    overflow: hidden;
  }

  // manipulate a very high logo to demonstrate this works
  cx-page-slot.SiteLogo img {
    height: 100px;
  }
}

结果(对徽标感到抱歉;))

选项 3:cx-header 出口

我想说你也应该能够使用插座,因为这会让你更接近选项 1(更改实际 DOM)。我想不出为什么它在 SmartEdit 中不起作用的原因 - 但很高兴了解是否是这种情况。在这种情况下,我建议使用 cx-header outletRef,这样您就可以替换整个 header.