Rap*_*let 23 web-component custom-element angular swiper.js
我实际上正在迁移到 Angular 15,并看到swiper 9 已经退出了。
它被写为一个简单npm i swiper且应该有效的方法,因为
所有主要浏览器和几乎所有框架都支持自定义元素。
但我有点迷失了,因为我无法再将其导入模块中
有人知道如何将最新的v9.0.0^swiper 版本与 Angular 一起使用吗?
Jus*_*lot 29
在AppModule中添加:
import {register} from 'swiper/element/bundle';
register();
Run Code Online (Sandbox Code Playgroud)
创建指令
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();
}
}
Run Code Online (Sandbox Code Playgroud)
在您的组件 ts 文件中添加
schemas: [CUSTOM_ELEMENTS_SCHEMA]
Run Code Online (Sandbox Code Playgroud)
设置您的 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
},
}
}
}
Run Code Online (Sandbox Code Playgroud)
和 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>
Run Code Online (Sandbox Code Playgroud)
这是我目前的解决方案。很高兴听到在 Angular 中实现新版本 Swiper 的更好方法:-)
小智 14
将 CUSTOM_ELEMENTS_SCHEMA 添加到 AppModule 的 @NgModule 装饰器中。这可以确保 Angular 编译并忽略未知的swiper-container和swiper-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 {}
Run Code Online (Sandbox Code Playgroud)
然后就可以将swiper-container和swiper-slide元素添加到模板中,但是代码不会做太多事情。初始化幻灯片时,我们需要调用文档中描述的寄存器函数。如果你查看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();
}
}
Run Code Online (Sandbox Code Playgroud)
可以通过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" (swiperactiveindexchange)="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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
swiper9 使使用变得简单,只需"schemas: [CUSTOM_ELEMENTS_SCHEMA],"在 module.ts 文件中提及组件的导入位置即可
//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();
Run Code Online (Sandbox Code Playgroud)
现在您的代码按预期工作“添加以下代码在 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>
Run Code Online (Sandbox Code Playgroud)
没有任何错误
尽管我已经接受这个答案作为解决方案,但实际上我必须执行以下操作。这需要我在swiper.js 文档中找到的一些想法
这是我能找到的最优化和最干净的版本。
import { register } from 'swiper/element/bundle'
constructor() {
register()
}
Run Code Online (Sandbox Code Playgroud)
register()应该只调用一次,所以这app.component.ts是该去的地方。<swiper-container
#swiperRef
init="false"
>
<swiper-slide *ngFor="let i of items; trackBy: trackByFn">
<!-- slide -->
</swiper-slide>
</swiper-container>
Run Code Online (Sandbox Code Playgroud)
init="false"如果您愿意的话,会让您准备选项。还可以让您订阅更改,例如slideChange.import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'
@NgModule({
// ...
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
Run Code Online (Sandbox Code Playgroud)
注意:您必须在将使用 swiper 元素的组件中声明它,不要全局声明它
@ViewChild('swiperRef', { static: true })
protected _swiperRef: ElementRef | undefined
swiper?: Swiper
ngOnInit() {
this._initSwiper()
}
private _initSwiper() {
const options: SwiperOptions = {
pagination: { clickable: true },
slidesPerView: 1,
breakpoints: this._getBreakpoints(), // In case you wish to calculate base on the `items` length
}
const swiperEl = this._swiperRef.nativeElement
Object.assign(swiperEl, options)
swiperEl.initialize()
if (this.swiper) this.swiper.currentBreakpoint = false // Breakpoint fixes
this.swiper = this._swiperRef.nativeElement.swiper
this.swiper.off('slideChange') // Avoid multiple subscription, in case you wish to call the `_initSwiper()` multiple time
this.swiper.on('slideChange', () => { // Any change subscription you wish
this.infinitLoad?.triggerOnScroll()
})
}
Run Code Online (Sandbox Code Playgroud)
注意:swiper-container 不得位于*ngIf. 如果是,请更改.component.ts文件中的以下内容。
@ViewChild('swiperRef', { static: false }) // Change to "false"
protected _swiperRef: ElementRef | undefined
itemsLoaded() { // Shall not be used in `ngOnInit` because it isn't rendered yet
this._initSwiper()
}
Run Code Online (Sandbox Code Playgroud)
swiper-container以避免使用 *ngIf| 归档时间: |
|
| 查看次数: |
26167 次 |
| 最近记录: |