Angular 14使用SplideJS Grid扩展报错及路由跳转滑块异常
修复方案
1. TS类型编译报错修复
该报错是@splidejs/splide-extension-grid包自身类型定义不兼容导致,禁止直接修改node_modules内的文件(依赖重新安装后修改会丢失)。在项目src目录下新增或修改typings.d.ts文件,添加如下类型合并声明即可跳过报错:
declare module '@splidejs/splide' { interface Components { Grid?: import('@splidejs/splide-extension-grid/dist/types/extensions/Grid/Grid').GridComponent; } }
2. 路由跳转后滑块消失问题修复
问题原因
- 滑块初始化时未将Grid扩展传入
mount方法,扩展未完成注册 - 路由跳转触发组件销毁时,未手动销毁Splide实例,DOM节点残留Splide生成的冗余结构,返回页面时初始化逻辑冲突
- 监听DOM变化时未判断实例是否已存在,重复创建实例导致渲染异常
修复后完整代码
组件TS代码
import { Component, OnInit, AfterViewInit, OnDestroy, ViewChildren, ViewChild, ElementRef } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import {Splide} from '@splidejs/splide'; import { Grid } from '@splidejs/splide-extension-grid'; import { Publications_Meta } from 'src/app/shared/interfaces/publication-meta.interface'; import { Publications } from 'src/app/shared/interfaces/publications.interface'; import { PublicationsService } from 'src/app/shared/services/publications.service'; @Component({ selector: 'app-publication', templateUrl: './publication.component.html' }) export class PublicationComponent implements OnInit, AfterViewInit, OnDestroy { publication! : Publications; publication_meta! : Publications_Meta; @ViewChild('gallery', {read: ElementRef}) gallery!: ElementRef; @ViewChildren("galleryitems") galleryitems: any; // 存储滑块实例,避免重复创建 private splideInstance?: Splide; constructor(private route: ActivatedRoute, public publicationsService : PublicationsService) {} private initSlider() { return new Splide( this.gallery.nativeElement, { perPage: 2, pagination: false, arrows: false, grid: { dimensions: [ [ 1, 1 ], [ 2, 2 ] ], gap : { row: '1rem', col: '1.5rem' }, }, breakpoints: { 600: { perPage: 1, grid: false, gap: '1rem', }, }, } ) } ngOnInit(): void { this.route.params .subscribe( params=> { this.publicationsService.getByID(params['id']) .subscribe( (publication) => { this.publication = publication as Publications; }); this.publicationsService.getMeta(params['id']) .subscribe( (publication_meta) => { this.publication_meta = publication_meta as Publications_Meta; }); }); } ngAfterViewInit(): void { this.galleryitems.changes.subscribe(() => { // 初始化前先销毁已存在的实例,清理DOM残留 if (this.splideInstance) { this.splideInstance.destroy(true); this.splideInstance = undefined; } // 无滑块项时跳过初始化 if (!this.galleryitems.length) return; this.splideInstance = this.initSlider(); // 注册Grid扩展后挂载 this.splideInstance.mount({ Grid }); }); } ngOnDestroy(): void { // 组件销毁时同步销毁滑块实例,避免内存泄漏 if (this.splideInstance) { this.splideInstance.destroy(true); this.splideInstance = undefined; } } }
模板HTML代码
移除冗余的固定id(已有模板变量获取元素,id重复可能引发潜在冲突),其余逻辑保持不变:
<div class="pub-gallery splide" #gallery> <div class="splide__track"> <ul class="splide__list"> <li #galleryitems class="splide__slide" *ngFor="let image of publication_meta.gallery; let i = index;"> <img [src]="image" [alt]="publication.titulo+i"> </li> </ul> </div> </div>
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

