You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:27:25