如何为Storybook Angular添加窗口大小调整事件监听器
解决Storybook Angular中窗口/视口调整时触发函数的问题
常规的@HostListener('window:resize')在Storybook环境中失效,主要源于Storybook的iframe隔离机制,以下是几个可行的解决方法:
方法1:使用RxJS监听resize事件(推荐)
通过RxJS的fromEvent创建resize事件流,配合防抖避免频繁触发,同时在组件销毁时取消订阅防止内存泄漏:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; @Component({ selector: 'app-your-tabs-component', templateUrl: './your-tabs-component.component.html' }) export class YourTabsComponent implements OnInit, OnDestroy { private resizeSubscription: any; ngOnInit(): void { // 监听窗口resize事件,防抖300ms减少触发频率 this.resizeSubscription = fromEvent(window, 'resize') .pipe(debounceTime(300)) .subscribe(() => { this.updateVisibleTabs(); // 调用你的标签数量计算函数 }); } ngOnDestroy(): void { // 组件销毁时取消订阅,避免内存泄漏 this.resizeSubscription?.unsubscribe(); } updateVisibleTabs(): void { // 你的计算屏幕尺寸、更新可见标签数量的逻辑 const screenWidth = window.innerWidth; // ... 其他业务逻辑 } }
方法2:通过DOCUMENT服务监听resize
注入Angular的DOCUMENT服务,获取当前窗口对象并绑定resize事件:
import { Component, OnInit, OnDestroy, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; @Component({ selector: 'app-your-tabs-component', templateUrl: './your-tabs-component.component.html' }) export class YourTabsComponent implements OnInit, OnDestroy { private resizeHandler: () => void; constructor(@Inject(DOCUMENT) private document: Document) {} ngOnInit(): void { this.resizeHandler = () => this.updateVisibleTabs(); // 绑定到当前窗口的resize事件 this.document.defaultView?.addEventListener('resize', this.resizeHandler); } ngOnDestroy(): void { // 移除事件监听 this.document.defaultView?.removeEventListener('resize', this.resizeHandler); } updateVisibleTabs(): void { // 你的业务逻辑 } }
方法3:适配Storybook视口切换事件
如果需要精准响应Storybook的视口切换操作(而非单纯窗口resize),可以在故事文件中利用Storybook的addons API监听视口变化:
import { Meta, Story } from '@storybook/angular'; import { YourTabsComponent } from './your-tabs-component.component'; export default { title: 'YourTabsComponent', component: YourTabsComponent, } as Meta; const Template: Story<YourTabsComponent> = (args: YourTabsComponent) => ({ component: YourTabsComponent, props: args, }); export const Default = Template.bind({}); Default.decorators = [ (story) => { // 监听Storybook视口切换事件 const viewportAddon = window['__STORYBOOK_ADDONS'].get('storybook/viewport'); viewportAddon.on('viewport:change', () => { // 获取组件实例并调用更新函数 const component = document.querySelector('app-your-tabs-component')?.componentInstance; component?.updateVisibleTabs(); }); return story(); }, ];
内容的提问来源于stack exchange,提问作者Anurag Singh
相关产品推荐
相关产品推荐

