写点什么

SAP 电商云 Spartacus UI 的响应式 UI 实现细节

作者:Jerry Wang
  • 2022 年 10 月 03 日
    四川
  • 本文字数:1171 字

    阅读完需:约 4 分钟

SAP 电商云 Spartacus UI 的响应式 UI 实现细节

在文件 projects\storefrontlib\layout\config\default-layout.config.ts 里,定义了各个屏幕尺寸所对应的 breakpoint:


export const defaultLayoutConfig: LayoutConfig = {  breakpoints: {    xs: 576,    sm: 768,    md: 992,    lg: 1200,    xl: {      min: 1200,    },  },};
复制代码



注意这个 breakpoint 和编程语言里的断点没有关系。


breakpoint.service.ts 的 getBreakpoint 方法,提供了根据当前屏幕宽度返回最合适的 breakpoint:



以这个 id 为 trigger 的按钮为例,它是完全 css 驱动的:



这个按钮的 css:


btn btn-action btn-block dialog-trigger


该按钮在 lg 这个 breakpoint 情况下,会被设置为 display:none:




而 Spartacus 应用代码怎么知道当前的屏幕尺寸对应的 break point 呢?


答案是我们自己实现的 breakpoint.service.ts.



首先定义枚举类型 BREAKPOINT:


export enum BREAKPOINT {  xs = 'xs',  sm = 'sm',  md = 'md',  lg = 'lg',  xl = 'xl',}
复制代码


然后根据当前代码的运行环境进行计算:


breakpoint$: Observable<BREAKPOINT> = isPlatformBrowser(this.platform)    ? this.winRef.resize$.pipe(        map((event) => this.getBreakpoint((<Window>event.target).innerWidth)),        distinctUntilChanged()      )    : of(this.fallbackBreakpoint);
constructor( protected winRef: WindowRef, protected layoutConfig: LayoutConfig, @Inject(PLATFORM_ID) protected platform: any ) {}
复制代码


如果当前运行在浏览器环境下,isPlatformBrowser(this.platform) 返回 true,那么进入三元表达式前面的分支,调用 this.getBreakpoint 根据当前屏幕的 innerWidth,获取对应的 breakpoint.


同时,一旦有 resize 事件发生,会自动重新计算新的 breakpoint. 每次 resize 事件发生时,产生的 event 对象 event.target 指向 Window 对象,该对象的 innerWidth 即是新的屏幕宽度。


如何捕捉屏幕的 resize 事件?


 get resize$(): Observable<any> {    if (!this.nativeWindow) {      return of(null);    } else {      return fromEvent(this.nativeWindow, 'resize').pipe(        debounceTime(300),        startWith({ target: this.nativeWindow }),        distinctUntilChanged()      );    }  }
复制代码


这里我们使用了 rxJs 的 fromEvent 和 debounce, 将 window 对象产生的 resize 事件,做了一个 300 毫秒的限流,意思是当 resize 事件触发后,如果 300 毫秒之内并没有新的 resize 事件发生时,再把这个 resize 事件,交给 Observable 执行链的下游处理,即重新获取 breakpoint.



如果当前代码在服务器端 Node.js 环境中运行,进入三元表达式问号后面的分支:of(this.fallbackBreakpoint);


返回最小屏幕尺寸对应的 breakpoint,这也体现了 mobile first 的设计思路。



发布于: 刚刚阅读数: 3
用户头像

Jerry Wang

关注

🏆InfoQ写作平台-签约作者🏆 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今。工作中使用 ABAP, Java, JavaScript 和 TypeScript 进行开发。

评论

发布
暂无评论
SAP 电商云 Spartacus UI 的响应式 UI 实现细节_前端_Jerry Wang_InfoQ写作社区