中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Angular2如何使用組件與指令實現圖片輪播組件

發布時間:2021-07-01 12:07:29 來源:億速云 閱讀:170 作者:小新 欄目:web開發

這篇文章主要介紹了Angular2如何使用組件與指令實現圖片輪播組件,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

一、創建組件

結束上文打的尷尬的比方,著眼于一個待開發的ng2項目,它有一個空白的特性頁面,現在需要在上面呈現一個圖片輪播窗口。

圖片輪播是一個需要給用戶看見的東西,所以應該使用ng2的組件(Component)來實現它,并且這個功能較為通用,可以將其獨立出來方便以后再次使用到。

所以在項目中的共享模塊(SharedModule)下創建這個組件名為 slide-img.component。

使用ng2提供的組建裝飾器來將這個TypeScript模塊正式變身成ng2的組件:

@Component({
 selector: 'my-slide-img',
 templateUrl: 'slide-img.component.html',
 styleUrls: ['slide-img.component.css'],
 animations: [
  trigger('imgMove', [
   /** 不顯示 */
   state('off', style({'display': 'none', 'z-index': '0', 'transform': 'translateX(0)'})),
   /** 上一張圖片 */
   state('prev', style({'z-index': '1',
   'transform': 'translateX(-100%)'})),
   /** 下一張圖片 */
   state('next', style({'z-index': '2', 'transform': 'translateX(100%)'})),
   /** 當前圖片 */
   state('on', style({'z-index': '3', 'transform': 'translateX(0)'})),
   transition('prev=>on', [
    animate('0.3s ease-in')
   ]),
   transition('next=>on', [
    animate('0.3s ease-in')
   ]),
   transition('on=>prev', [
    animate('0.3s ease-in')
   ]),
   transition('on=>next', [
    animate('0.3s ease-in')
   ])
  ])
 ]
})
export class SlideImgComponent { }

其參數其實已經不能再明確了:

  selector就是其使用時的標簽名,

  templateUrl即組件關聯的界面的模板,

  styleUrls即僅在此組件內生效的樣式表,

  animations定義的是一套ng2動畫規則。

講講最后的這個動畫規則:

ng2的動畫其實非常簡單,步驟為1.定義觸發器名,2.定義狀態,3.定義切換樣式,4.將此觸發器應用到具體的標簽中,狀態作為觸發器的值傳入。

當ng2檢測到動畫狀態的值更改了,就會套用定義的切換樣式,用法思路還算比較明確(當然實際使用時會有一些尷尬的小問題)

二、實現組件

既然是輪播圖片組件,要做的事情首先就得是傳入輪播圖片然后顯示出來。

使用過ng1的朋友一定還記得其在定義指令(angular.directive)的時候是通過scope參數(或者link)來傳入數據的,而ng2中使用的是Input裝飾器,使用的方法如下:

@Input() public imgs: SlideImg[];

使用了此裝飾器的變量imgs將可以在運行時接收其他組件傳入的圖片列表。使用方法如下:

<my-slide-img [imgs]="imgs"></my-slide-img>

關于這里的方括號“[]”,ng2其實提供了多種方式來進行組件模板中值的傳入,其中這種變量名用方括號包起來的方法就是其中之一,代表是輸入的值,而后面會見到的圓括號來包圍的方式,是代表輸出的值。

傳入了數據后,下一步就是要如何來顯示圖片到界面上了,沒錯就是ng1中ng-for指令的升級版*ngFor,除了寫法外表面上的差別不大。

關于輪播圖片邏輯的具體實現邏輯,筆者使用的方式就是利用ng2動畫的狀態切換,設置一個當前圖片索引值current,*ngFor渲染的圖片將其索引與當前索引比較,如果是相鄰的圖片則設為'prev'狀態與'next'狀態,ng2會為其加上位置屬性為-100%或者100%,如果是當前圖片則設為'on'狀態,ng2會將其的位置屬性設為0,其余均設為'off'狀態,ng2會直接將其隱藏,實現的邏輯很簡單,考慮也不算周全,筆者就不繼續解釋獻丑了。

最終的輪播圖片組件及其模板文件代碼如下:

<div class="imgs">
 <img src="{{img.Url}}" alt="" class="img"
 *ngFor="let img of imgs;let i=index"
 (mySwipe)="Change($event)"
 [@imgMove]="ImgState(i)">
</div>

<div class="btn" (click)="Prev()">Prev</div>
<div class="btn" (click)="Next()">Next</div>
.imgs{
 position: relative;width: 100%;height: 15em;
 overflow: hidden;
}
.img{
 position: absolute;
 width: 100%;
 height: 100%;
 background: pink;
 transition: 0.2s;
}
.btn{
 display: inline-block;
 padding: 1em 2em;font-size: 1em;border-radius: 0.5em;
 border: 1px solid #ddd;cursor: pointer;
 margin: 1em;background: #eee;box-shadow: 0.1em 0.1em 0.2em #aaa;
}
.btn:active{
 background: #eee;
 box-shadow: none;
}
import { Component, OnInit, Input,
 animate,
 style,
 transition,
 trigger,
 state,
 HostListener
} from '@angular/core';
import { SlideImg } from './slide-img.interface';

@Component({
 selector: 'my-slide-img',
 templateUrl: 'slide-img.component.html',
 styleUrls: ['slide-img.component.css'],
 animations: [
  trigger('imgMove', [
   /** 不顯示 */
   state('off', style({'display': 'none', 'z-index': '0', 'transform': 'translateX(0)'})),
   /** 上一張圖片 */
   state('prev', style({'z-index': '1',
   'transform': 'translateX(-100%)'})),
   /** 下一張圖片 */
   state('next', style({'z-index': '2', 'transform': 'translateX(100%)'})),
   /** 當前圖片 */
   state('on', style({'z-index': '3', 'transform': 'translateX(0)'})),
   transition('prev=>on', [
    animate('0.3s ease-in')
   ]),
   transition('next=>on', [
    animate('0.3s ease-in')
   ]),
   transition('on=>prev', [
    animate('0.3s ease-in')
   ]),
   transition('on=>next', [
    animate('0.3s ease-in')
   ])
  ])
 ]
})
export class SlideImgComponent {
 @Input() public imgs: SlideImg[];
 public current;
 constructor() {
  this.current = 0;
 }
 public ImgState(index) {
  if (this.imgs && this.imgs.length) {
   if (this.current === 0) {
    return index === 0 ? 'on' :
    index === 1 ? 'next' :
    index === this.imgs.length - 1 ? 'prev' :
    'off';
   } else if (this.current === this.imgs.length - 1) {
    return index === this.imgs.length - 1 ? 'on' :
    index === this.imgs.length - 2 ? 'prev' :
    index === 0 ? 'next' :
    'off';
   }
   switch (index - this.current) {
    case 0:
     return 'on';
    case 1:
     return 'next';
    case -1:
     return 'prev';
    default:
     return 'off';
   }
  } else {
   return 'off';
  }
 }
 public Next() {
  this.current = (this.current + 1) % this.imgs.length;
 }
 public Prev() {
  this.current = this.current - 1 < 0 ? this.imgs.length - 1 : this.current - 1;
 }

 public Change(e) {
  if (e === 'left') {
   this.Next();
  } else if (e === 'right') {
   this.Prev();
  }
 }
}

其中有兩個地方為講到,一個是組件代碼引入了一個slide-img.interface 模塊,這個僅僅用來規范一下輪播圖片的格式,二是在html中還有一個節點名為(mySwipe)這就是接下來要講的輸出屬性,目前知道的它的作用是,當用戶滑動圖片時,將觸發此節點配置的回調方法,所做的事情就是判斷發生了左滑事件還是右滑事件,分別觸發上一張圖或下一張圖的切換。

三、給輪播圖片控件加上手勢效果

輪播圖片在移動端很需要加上手勢滑動的效果,所以接下來要給這個輪播組件加上一個指令,用于響應用戶的滑動手勢。代碼如下:

import { Directive, Input, HostListener, Output, EventEmitter } from '@angular/core';

@Directive({ selector: '[mySwipe]' })
export class SwipeDirective {
 @Output() public mySwipe = new EventEmitter<string>();

 private touchStartX;
 private touchStartY;
 @HostListener('touchstart', ['$event']) public onTouchStart(e) {
  this.touchStartX = e.changedTouches[0].clientX;
  this.touchStartY = e.changedTouches[0].clientY;
 }
 @HostListener('touchend', ['$event']) public onTouchEnd(e) {
  let moveX = e.changedTouches[0].clientX - this.touchStartX;
  let moveY = e.changedTouches[0].clientY - this.touchStartY;
  if (Math.abs(moveY) < Math.abs(moveX)) {
   /**
    * Y軸移動小于X軸 判定為橫向滑動
    */
   if (moveX > 50) {
    this.mySwipe.emit('right');
   } else if (moveX < -50) {
    this.mySwipe.emit('left');
   }
  } else if (Math.abs(moveY) > Math.abs(moveX)) {
   /**
    * Y軸移動大于X軸 判定為縱向滑動
    */
   if (moveY > 50) {
    this.mySwipe.emit('down');
   } else if (moveY < -50) {
    this.mySwipe.emit('up');
   }
  }
  this.touchStartX = this.touchStartY = -1;
 }
}

指令的聲明甚至簡單過組建的聲明,因為指令不需要依賴于某個視圖模板,只需要有個指令名稱就足夠了。

需要關心的是指令中定義的輸出屬性:

@Output() public mySwipe = new EventEmitter<string>();

此屬性接收了上文組件中的Change($event)回調方法,在此指令中,所做的事情就是監聽組件的滑動,收到滑動事件后就觸發這個回調,監聽使用的是ng2的HostListener裝飾器,用法顯而易見了。

現在運行起項目來看看效果吧(比較懶就不截動圖了):

Angular2如何使用組件與指令實現圖片輪播組件

總結以及題外話:

本文主要使用了ng2幾個比較基本的功能——輸入屬性(Input裝飾器)、輸出屬性(Outut裝飾器)、HostListener裝飾器、幾個系統指令(ngFor)、ng2動畫實現了一個比較基本的圖片輪播控件。

使用好ng2的組件以及指令能完成很多的事情,其需要學習的東西絕不僅限與本文提到的,包括其底層的渲染,也很值得去研究。

最后提一個尷尬的問題點:

其實最初寫這個輪播圖片的時候想過要加上拖動的,也就是圖片會隨手勢的滑動實時更新位置。

但后來發現ng2的動畫有個尷尬的地方,那就是一定會從初始狀態按照定義好的轉換效果變化到目標狀態。實時滑動需要我在滑動過程中就改變圖片的位置,這樣的話在滑動結束需要切換圖片時,圖片居然強行回到了初始位置然后才開始轉換動畫,一時還想不到繼續使用ng2動畫來實現這種實時滑動的完美解決辦法,實在是尷尬。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Angular2如何使用組件與指令實現圖片輪播組件”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

双辽市| 读书| 额尔古纳市| 成安县| 常宁市| 台州市| 浦县| 图木舒克市| 南城县| 芦山县| 禄丰县| 白银市| 抚远县| 余姚市| 靖宇县| 青铜峡市| 环江| 马关县| 南陵县| 朝阳市| 酉阳| 永新县| 元氏县| 河池市| 黑山县| 广安市| 长兴县| 宝兴县| 伊宁市| 兴安盟| 安丘市| 青河县| 云林县| 中阳县| 茌平县| 云阳县| 永靖县| 呼图壁县| 错那县| 石屏县| 峡江县|