注冊(cè)登錄

基于angular實(shí)現(xiàn)模擬微信小程序swiper組件

2020-09-28
導(dǎo)讀:這段時(shí)間的主業(yè)是完成一個(gè)家政類小程序,終于是過審核發(fā)布了。不得不說微信的這個(gè)小程序生態(tài)還是頗有想法的,拋開他現(xiàn)有的一些問題不說,其提供的 組件 系統(tǒng) 乍一看還是蠻酷的...

這段時(shí)間的主業(yè)是完成一個(gè)家政類小程序,終于是過審核發(fā)布了。不得不說微信的這個(gè)小程序生態(tài)還是頗有想法的,拋開他現(xiàn)有的一些問題不說,其提供的組件系統(tǒng)乍一看還是蠻酷的。比如其提供的一個(gè)叫swiper的視圖組件,就可以在寫界面的時(shí)候省不少時(shí)間和代碼,輪播圖片跟可滑動(dòng)列表都可以用。導(dǎo)致現(xiàn)在回來寫angular項(xiàng)目時(shí)也想整一個(gè)這樣的組件出來,本文就將使用angular的組件能力和服務(wù)能力完成這么一個(gè)比較通用,耦合度較低的swiper出來。

首先要選擇使用的技術(shù),要實(shí)現(xiàn)的是與界面打交道的東西,自然是實(shí)現(xiàn)成一個(gè)組件,最終要實(shí)現(xiàn)的效果是寫下這樣的代碼就可以完成一個(gè)可以滑動(dòng)的視圖來:

然后要把最基本的組件定義寫出來,顯然這里要定義兩個(gè)組件。第一個(gè)是父級(jí)組件,選擇器名字就叫ytm-swipers,目前做的事情僅僅是做一個(gè)外殼定義基本樣式,使用時(shí)的子標(biāo)簽都會(huì)插入在ng-content標(biāo)簽中。

基于angular實(shí)現(xiàn)模擬微信小程序swiper組件

 

 1 @Component({
 2     selector: 'ytm-swipers',
 3     template: `
 4         

5 6

7 `, 8 styles: [` 9 .view-body{height: 100%;width: 100%;overflow: hidden;position: relative;} 10 `] 11 })

 

第二個(gè)就是子視圖了,在父級(jí)組件下,每個(gè)子組件都會(huì)沾滿父級(jí)組件,只有當(dāng)前的子組件會(huì)顯示,當(dāng)切換視圖時(shí)實(shí)際做的就是更改這些子組件的顯示方式,說的最簡(jiǎn)單的話,這個(gè)子組件還是僅僅用來加一個(gè)子外殼,給外殼添加基本樣式,實(shí)際的頁(yè)面內(nèi)容原封不動(dòng)放在ng-content標(biāo)簽中。

 

 1 @Component({
 2     selector: 'swiper',
 3     template: `
 4         

7 8

9 `, 10 styles: [` 11 .view-child{ 12 height: 100%;width: 100%;position: absolute;top: 0; 13 transition: 0.5s linear;background: #fff; 14 overflow-x: hidden; 15 } 16 .view-child.active{left: 0;z-index: 9;} 17 .view-child.next{left: 100%;z-index: 7;} 18 .view-child.prev{left: -100%;z-index: 8;} 19 `] 20 })

 

下一步是要讓這兩個(gè)父子組件完成心靈的溝通,講道理其實(shí)可以直接使用ElementRef強(qiáng)行取到DOM來操作,不過這里使用的是組件內(nèi)服務(wù)。和普通的服務(wù)使用上沒差別,不過其provider是聲明在某個(gè)組件里的,所以此服務(wù)只有在此組件以及子組件中可以注入使用。

基于angular實(shí)現(xiàn)模擬微信小程序swiper組件組件內(nèi)服務(wù)

用到的變量包括: changing變量保證同時(shí)只能進(jìn)行一個(gè)切換,保證切換完成才能進(jìn)行下一個(gè)切換;swiperList裝填所有的視圖的id,這個(gè)id在視圖初始化的時(shí)候生成;displayList數(shù)組只會(huì)有三個(gè)成員,裝填的依次是當(dāng)前視圖在swiperList中的索引,下一個(gè)視圖的索引,上一個(gè)視圖的索引;current變量用戶指示當(dāng)前顯示的視圖的id。實(shí)際視圖中的顯示的控制就是使用ngClass指令來根據(jù)displayList和視圖id附加相應(yīng)的類,當(dāng)前視圖會(huì)正好顯示,前一視圖會(huì)在左邊剛好遮擋,后一視圖會(huì)在右邊剛好遮擋。

同時(shí)服務(wù)還要提供幾個(gè)方法:Add用于添加制定id的視圖,Next用于切換到下一個(gè)視圖(左滑時(shí)調(diào)用),Prev用于切換到前一個(gè)視圖(右滑時(shí)調(diào)用),再來一個(gè)Skip用于直接切換到指定id的視圖。

在子視圖中注入此服務(wù),需要在子視圖初始化時(shí)生成一個(gè)id并Add到視圖列表中:

 

1 export class YTMSwiperViewComponent {
2     public childId: number;
3     constructor(@Optional() @Host() public swiper: SwiperService) {
4         this.childId = this.swiper.swiperList.length;
5         this.swiper.Add(this.swiper.swiperList.length);
6     }
7 }

 

這個(gè)id其實(shí)就是已有列表的索引累加,且一旦有新視圖被初始化,都會(huì)添加到列表中(支持動(dòng)態(tài)加入很酷,雖然不知道會(huì)有什么隱藏問題發(fā)生)。

父組件中首先必須要配置一個(gè)provider聲明服務(wù):

 

 1 @Component({
 2     selector: 'ytm-swipers',
 3     template: `
 4         

5 6

7 `, 8 styles: [` 9 .view-body{height: 100%;width: 100%;overflow: hidden;position: relative;} 10 `], 11 providers: [SwiperService] 12 })

 

然后就是要監(jiān)聽手勢(shì)滑動(dòng)事件,做出相應(yīng)的切換。以及傳入一個(gè)current變量,每當(dāng)此變量更新時(shí)都要切換到對(duì)應(yīng)id的視圖去,實(shí)際使用效果就是:

...可以將視圖切換到id喂1的視圖也就是第二個(gè)視圖。

基于angular實(shí)現(xiàn)模擬微信小程序swiper組件父組件實(shí)現(xiàn)

此外代碼中還添加了一個(gè)回調(diào)函數(shù),可以再視圖完成切換時(shí)執(zhí)行傳入的回調(diào),這個(gè)使用的是angular的EventEmitter能力。

以上就是全部實(shí)現(xiàn)了,實(shí)際的使用示例像這樣:

視圖的切換有了兩種方式,一是手勢(shì)滑動(dòng),不過沒有寫實(shí)時(shí)拖動(dòng),僅僅是判斷左右滑做出反應(yīng)罷了,二是更新[current]節(jié)點(diǎn)的值。

整個(gè)組件的實(shí)現(xiàn)沒有使用到angular一些比較底層的能力,僅僅是玩弄css樣式以及組件嵌套并通過服務(wù)交互,以及Input、Output與外界交互。相比之下ionic的那些組件就厲害深?yuàn)W多了,筆者還有很長(zhǎng)的路要走。

重磅推薦:小程序開店目錄

第一部分:小商店是什么

第二部分:如何開通一個(gè)小商店

第三部分:如何登錄小商店

第四部分:開店任務(wù)常見問題

第五部分:小商店可以賣什么

第六部分:HiShop小程序特色功能

第七部分:小程序直播

第八部分:小程序收貨/物流

第九部分:小程序怎么結(jié)算

第十部分:小程序客服

第十一部分:電商創(chuàng)業(yè)

第十二部分:小程序游戲開發(fā)

電話咨詢 微信咨詢 預(yù)約演示 0元開店