如何使用 swiper 9 with angular

问题描述 投票:0回答:6

我实际上正在迁移到 Angular 15 并看到 swiper 9 已经出来了.

写了一个简单的

npm i swiper
它应该可以工作,因为

所有主流浏览器和几乎所有框架都支持自定义元素。

但是我有点迷路了,因为我不能再在模块中导入它了

有人知道如何使用最新的

v9.0.0^
swiper 版本吗?

angular web-component swiper.js custom-element
6个回答
9
投票

在 AppModule 添加:

import {register} from 'swiper/element/bundle';

register();

创建指令

import {AfterViewInit, Directive, ElementRef, Input} from '@angular/core';
import {SwiperOptions} from "swiper";

@Directive({
  selector: '[fmSwiper]',
  standalone: true,
})
export class SwiperDirective implements AfterViewInit {

  private readonly swiperElement: HTMLElement;

  @Input('config')
  config?: SwiperOptions;

  constructor(private el: ElementRef<HTMLElement>) {
    this.swiperElement = el.nativeElement;
  }

  ngAfterViewInit() {
    Object.assign(this.el.nativeElement, this.config);
    
    // @ts-ignore
    this.el.nativeElement.initialize();
  }
}

在你的组件 ts 文件中添加

schemas: [CUSTOM_ELEMENTS_SCHEMA]

设置您的 Swiper 配置。

例子:

import {Component, CUSTOM_ELEMENTS_SCHEMA, ViewEncapsulation} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MainHeadingComponent} from "../main-heading/main-heading.component";
import {StreamItemComponent} from "./stream-item/stream-item.component";
import {A11y, Mousewheel, Navigation, Pagination, SwiperOptions} from 'swiper';
import {SwiperDirective} from "../../directives/swiper.directive";

@Component({
  selector: 'fm-streams-swiper',
  standalone: true,
  encapsulation: ViewEncapsulation.None,
  imports: [
    CommonModule,
    MainHeadingComponent,
    StreamItemComponent,
    SwiperDirective
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  templateUrl: './streams-swiper.component.html',
})
export class StreamsSwiperComponent {

  sliders: string[] = [
    'Test 1',
    'Test 2',
    'Test 3',
    'Test 4',
    'Test 5',
    'Test 6',
    'Test 7',
    'Test 8',
    'Test 9',
  ]

  public config: SwiperOptions = {
    modules: [Navigation, Pagination, A11y, Mousewheel],
    autoHeight: true,
    spaceBetween: 20,
    navigation: false,
    pagination: {clickable: true, dynamicBullets: true},
    slidesPerView: 1,
    centeredSlides: true,
    breakpoints: {
      400: {
        slidesPerView: "auto",
        centeredSlides: false
      },
    }
  }
}

和 HMTL 文件:

  <swiper-container fmSwiper [config]="config" init="false" class="w-full">
    <swiper-slide class="w-[310px] sm:w-[450px] pb-6"
         *ngFor="let slider of sliders">
      <fm-stream-item></fm-stream-item>
    </swiper-slide>
  </swiper-container>

这是我目前的解决方案。很高兴听到更好的方法来在 Angular 中实现新版本的 Swiper :-)

Swiper 元素:核心版本和模块


4
投票

将 CUSTOM_ELEMENTS_SCHEMA 添加到 AppModule 的 @NgModule 装饰器。这确保了 Angular 编译并忽略未知的 swiper-containerswiper-slide 自定义元素并且编译没有错误。

import {CUSTOM_ELEMENTS_SCHEMA, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {}

然后可以将 swiper-containerswiper-slide 元素添加到模板中,但是代码不会做太多事情。初始化幻灯片,我们需要调用 register 函数,如 documentation 中所述。如果您查看source code Swiper,它表明此函数需要初始化 DOM。这意味着您应该将它放在组件和 ngAfterViewInit 生命周期挂钩中。这为我们提供了以下代码(请注意,参数 可以在 kebab-case 中传递):

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
import {register} from 'swiper/element/bundle';

@Component({
  selector: 'app-root',
  template: `
    <swiper-container initial-slide="0" slides-per-view="1">
      <swiper-slide>
        <h1>Slide 1</h1>
      </swiper-slide>
      <swiper-slide>
        <h1>Slide 2</h1>
      </swiper-slide>
      <swiper-slide>
        <h1>Slide 3</h1>
      </swiper-slide>
    </swiper-container>
  `,
})
export class AppComponent implements AfterViewInit {

  ngAfterViewInit(): void {
    register();
  }
}

可以通过ViewChild装饰器来访问Swiper实例。为了演示这一点,我包含了一个函数,每次幻灯片更改时,它都会将当前幻灯片的索引打印到控制台。并不是说文档中描述的所有事件都可用,但必须写成小写。

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
import {register} from 'swiper/element/bundle';
import {Swiper} from 'swiper/types';

@Component({
  selector: 'app-root',
  template: `
    <swiper-container #swiperRef initial-slide="0" (activeindexchange)="onActiveIndexChange()" slides-per-view="1">
      <swiper-slide>
        <h1>Slide 1</h1>
      </swiper-slide>
      <swiper-slide>
        <h1>Slide 2</h1>
      </swiper-slide>
      <swiper-slide>
        <h1>Slide 3</h1>
      </swiper-slide>
    </swiper-container>
  `,
})
export class AppComponent implements AfterViewInit {
  @ViewChild('swiperRef')
  swiperRef: ElementRef | undefined;
  swiper?: Swiper;

  ngAfterViewInit(): void {
    register();
    this.swiper = this.swiperRef?.nativeElement.swiper;
  }

  onActiveIndexChange() {
    console.log(this.swiper?.activeIndex);
  }
}

2
投票

我刚刚将一个项目从 Swiper 8 升级到 Swiper 9,并面临同样的初始困惑。显然他们取消了 Swiper 中的 Angular 组件,并希望我们使用 Swiper Elements。

https://swiperjs.com/element#swiper-custom-elements-from-cdn

这不是一个理想的“Angular”解决方案,但我希望他们做出这个决定是为了尽可能多地兼容框架。

要完成这项工作,只需创建一个 div 布局,其中包含类“swiper”、“swiper-wrapper”和“swiper-slide”,其中包装器位于 swiper 内,幻灯片位于包装器内。在 ts 文件中导入 Swiper 并创建该类的新实例并将其定向到文件“.swiper”。

我的代码是这样的:

this.swiper = new Swiper('.swiper', {
            modules: [Navigation, Pagination, Autoplay],
            speed: 4000,
            effect: 'flip',
            spaceBetween: 0,
            navigation: false,
            autoplay: {
              delay: 3500,
              disableOnInteraction: true
            },
            slidesPerView: 1,
            pagination: { clickable: true },
            scrollbar: { draggable: true }
          });

1
投票

如果您想手动初始化(使用 init="false"),您可以使用这些类型来完成。

在 themplate.html 中

<swiper-container init="false" class="pager" #swiper>
    <swiper-slide *ngFor="[...]">
    </swiper-slide>
</swiper-container>

在组件中

@Component({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
// [...]
})
export class NewsPagerComponent implements AfterViewInit, OnInit {
  @ViewChild('swiper') swiperRef: ElementRef<HTMLElement & { swiper?: Swiper } & { initialize: () => void }> | undefined;
  swiper?: Swiper;
  
  ngOnInit(): void {
    register();
  }

  ngAfterViewInit(): void {
    const swiperEl = Object.assign(this.swiperRef.nativeElement, {
      modules: [Navigation],
      navigation: true
    });
    swiperEl.initialize();

    this.swiper = this.swiperRef.nativeElement.swiper;
  }
}

现在你有工具可以按照 swiper-element 的官方文档来做任何事情。


0
投票

El componente hijo va tener el siguiente código, aqui vamos a renderizar el swiper

swiper.component.html

<swiper-container #swiperContainer init="false">
  <swiper-slide *ngFor="let item_ of data">
    <ng-container
      *ngIf="bodyTemplateRef"
      [ngTemplateOutlet]="bodyTemplateRef"
      [ngTemplateOutletContext]="{ $implicit: item_ }"
    ></ng-container>
  </swiper-slide>
</swiper-container>

swiper.component.ts

import {
  AfterViewInit,
  Component,
  ContentChild,
  CUSTOM_ELEMENTS_SCHEMA,
  ElementRef,
  Input,
  TemplateRef,
  ViewChild,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { SwiperOptions } from 'swiper';
import { register } from 'swiper/element/bundle';

register();

@Component({
  selector: 'app-swiper',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './swiper.component.html',
  styleUrls: ['./swiper.component.scss'],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class SwiperComponent implements AfterViewInit {

  @ContentChild('body', { static: false }) bodyTemplateRef?: TemplateRef<any>;
  @ViewChild("swiperContainer", { static: true }) swiperContainer!: ElementRef<HTMLElement>

  @Input('config') config?: SwiperOptions
  @Input('data') data: any[] = []

  ngAfterViewInit(): void {
    Object.assign(this.swiperContainer.nativeElement, this.config);
    (this.swiperContainer.nativeElement as any).initialize();
  }

}

父组件:

El componente padre recibe el item que puedes usar para construir el contenido

<app-swiper [config]="swiperConfig" [data]="companies">
  <ng-template let-item_ #body>
    <!-- content {{ item_ }} -->
  </ng-template>
</app-swiper>

0
投票

swiper9 使其易于使用,只需在导入组件的 module.ts 文件中提及

"schemas: [CUSTOM_ELEMENTS_SCHEMA],"

//below steps are for module.ts file
// 1 step : 
import { CUSTOM_ELEMENTS_SCHEMA,} from '@angular/core';

// 2nd step: 
mention "schemas: [CUSTOM_ELEMENTS_SCHEMA]," inside @NgModule 

// 3rd step : 
import { register } from 'swiper/element/bundle';
              
// and  
register();

现在您的代码按预期工作“添加以下代码在 html 文件中”

<swiper-container #swiper initial-slide="0">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  <swiper-slide>Slide 4</swiper-slide>
  <swiper-slide>Slide 5</swiper-slide>
  <swiper-slide>Slide 6</swiper-slide>
  <swiper-slide>Slide 7</swiper-slide>
  <swiper-slide>Slide 8</swiper-slide>
  <swiper-slide>Slide 9</swiper-slide>
</swiper-container>

没有任何错误

© www.soinside.com 2019 - 2024. All rights reserved.