Vue組件實(shí)現(xiàn)景深卡片輪播示例
前言
朋友的朋友做了個(gè)首頁(yè),首頁(yè)用到一個(gè)卡片輪播,大概就是這個(gè)樣子的:
第一版他們是開(kāi)發(fā)出來(lái)了,但是各種bug,希望我?guī)兔Ω囊幌隆?/p>
看完代碼以后,發(fā)現(xiàn)他們整合了一個(gè)縫合怪出來(lái),各個(gè)樓層都是從其他地方 CV 過(guò)來(lái)的,而且各個(gè)樓層引用了 n 多個(gè)js 和 css 文件,看了一下效果以后,覺(jué)得改他的東西確實(shí)比重新開(kāi)發(fā)一個(gè)要麻煩的多得多,所以就重新寫了一下。
在此記錄一下,以便于后續(xù)復(fù)用。
需求拆解
- 初始化渲染5個(gè)容器,用來(lái)承載圖片和標(biāo)題,按照景深的效果排列,越靠近自己越大。
- 點(diǎn)擊中間一塊的左邊的整體向右旋轉(zhuǎn)一格,點(diǎn)擊右邊的向左旋轉(zhuǎn)一格,點(diǎn)擊中間的沒(méi)有效果。
- 中間一項(xiàng)顯示 content 和 查看更多 按鈕,其他不顯示。
開(kāi)發(fā)思路(vue2)
- 景深效果可以選擇使用 css3 的轉(zhuǎn)換來(lái)制作,通過(guò)對(duì)每個(gè)容器進(jìn)行不通比例的縮放來(lái)實(shí)現(xiàn)5個(gè)容器大小不一致的效果。
- 因?yàn)槭褂玫搅薱ss3的轉(zhuǎn)換,就需要用到過(guò)渡,動(dòng)畫效果就使用 transition-group 來(lái)實(shí)現(xiàn)。
- 至此就可以輪播就可以滾動(dòng)起來(lái)了,只需要給5個(gè)容器循環(huán)賦值css樣式,就可以實(shí)現(xiàn)縮放和位置轉(zhuǎn)換,結(jié)合漸變,就成了一個(gè)循環(huán)動(dòng)畫效果。
- 點(diǎn)擊事件,一開(kāi)始的思路是通過(guò)獲取點(diǎn)擊事件中的鼠標(biāo)的坐標(biāo),如果在左半個(gè)屏幕就走左邊的邏輯,但是頁(yè)面有個(gè)最小寬度 1280,當(dāng)分辨率被拖動(dòng)的時(shí)候就不行了,所以pass掉了。最后選擇的方案是,給容器一套下標(biāo)(_id)的同時(shí)全局聲明一個(gè)變量用來(lái)記錄當(dāng)前展示的容器的下標(biāo),每次點(diǎn)擊都要和展示項(xiàng)作比較,通過(guò)比較結(jié)果來(lái)確定左右邏輯。
- 思維發(fā)散:
- 可以擴(kuò)展為7個(gè)甚至更多容器的輪播
- 擴(kuò)展為n個(gè)容器,但是只顯示5個(gè)的輪播
- 景深效果以及動(dòng)畫效果改變
- ...
開(kāi)發(fā)過(guò)程
首先是html+css部分,這部分很簡(jiǎn)單,而且很普通。
- 寫 5 個(gè)div,每個(gè)都用絕對(duì)定位的方式鋪滿整個(gè)屏幕,每個(gè)寬度都是 20%。
- 綁定各數(shù)據(jù),并用 幾個(gè) 狀態(tài)值來(lái)控制 content 的顯示隱藏,以及當(dāng)前展示項(xiàng)。
代碼如下:
<script> // 引入圖片資源 import loop1 from '@assets/images/loop1.png'; import loop2 from '@assets/images/loop2.png'; import loop3 from '@assets/images/loop3.png'; import loop4 from '@assets/images/loop4.png'; import loop5 from '@assets/images/loop5.png'; /** * 根據(jù) id 獲取下標(biāo) * @params arr object[] * @params id number * @result number n>=-1 */ const findIdxById = (arr, id) => { for (let i = 0; i < arr.length; i++) { if (arr[i] === id) { return i; } } return -1; }; export default { data() { return { // 輪播數(shù)據(jù) baseData: [ { desc: '可折疊式智能移動(dòng)影院Royle-X展現(xiàn)了驚人的高科技技術(shù)和全球首創(chuàng)的可折疊設(shè)計(jì),配備了柔宇科技自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折疊計(jì)自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化。可能會(huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折', title: '這里是標(biāo)題', cover: loop1, }, { desc: '可折疊式智能移動(dòng)影院Royle-X展現(xiàn)了驚人的高科技技術(shù)和全球首創(chuàng)的可折疊設(shè)計(jì),配備了柔宇科技自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折疊計(jì)自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折', title: '這里是標(biāo)題', cover: loop2, }, { desc: '可折疊式智能移動(dòng)影院Royle-X展現(xiàn)了驚人的高科技技術(shù)和全球首創(chuàng)的可折疊設(shè)計(jì),配備了柔宇科技自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折疊計(jì)自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化。可能會(huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折', title: '這里是標(biāo)題', cover: loop3, }, { desc: '可折疊式智能移動(dòng)影院Royle-X展現(xiàn)了驚人的高科技技術(shù)和全球首創(chuàng)的可折疊設(shè)計(jì),配備了柔宇科技自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折疊計(jì)自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化。可能會(huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折', title: '這里是標(biāo)題', cover: loop4, }, { desc: '可折疊式智能移動(dòng)影院Royle-X展現(xiàn)了驚人的高科技技術(shù)和全球首創(chuàng)的可折疊設(shè)計(jì),配備了柔宇科技自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折疊計(jì)自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折自助研發(fā)的首款智能移動(dòng)顯示操作系統(tǒng),設(shè)計(jì)非常人性化??赡軙?huì)可折', title: '這里是標(biāo)題', cover: loop5, }, ], // 當(dāng)前展示項(xiàng) loopCenterIdx: 2, // 輪播樣式模板,用來(lái)循環(huán)賦值給 容器 loopModules: [ { loopIdx: 0, style: { 'z-index': 7, background: '#fff', transform: `scale(${1})`, left: 'calc(100% / 5 * 0)', height: '320px', opacity: 0.8, }, }, { loopIdx: 1, style: { 'z-index': 8, transform: `scale(${1.4})`, background: '#fff', left: 'calc(100% / 5 * .9)', height: '320px', opacity: 0.9, }, }, { loopIdx: 2, style: { transform: `scale(${1.7})`, 'z-index': 9, background: '#fff', left: 'calc(100% / 5 * 2)', opacity: 1, 'box-shadow': '0 0 5px #ccc', height: '370px', }, }, { loopIdx: 3, style: { transform: `scale(${1.4})`, 'z-index': 8, background: '#fff', left: 'calc(100% / 5 * 3.1)', opacity: 0.9, height: '320px', }, }, { loopIdx: 4, style: { 'z-index': 7, transform: `scale(${1})`, background: '#fff', left: 'calc(100% / 5 * 4)', height: '320px', opacity: 0.8, }, }, ], }; }, created(){ // todo Ajax ... }, mounted() { // 初始化輪播 this.initLoop(); console.log('centerIdx = ', this.loopCenterIdx); }, methods: { // 初始化輪播 initLoop() { this.loopModules = this.loopModules.map((item, idx) => { item.desc = this.baseData[idx]; return item; }); console.log(this.loopModules); }, // 下一張 handleNext() { this.loopCenterIdx = this.loopCenterIdx + 1 > 4 ? 0 : this.loopCenterIdx + 1; this.loopModules = this.loopModules.map((item, idx) => { item.desc = this.baseData[idx]; return item; }); this.loopModules.unshift(this.loopModules.pop()); }, // 上一張 handleLast() { this.loopCenterIdx = this.loopCenterIdx - 1 < 0 ? 4 : this.loopCenterIdx - 1; this.loopModules = this.loopModules.map((item, idx) => { item.desc = this.baseData[idx]; return item; }); this.loopModules.push(this.loopModules.shift()); }, // 點(diǎn)擊容器 handleLoop(checkId) { console.log('checkId = ', checkId, ', loopCenterIdx = ', this.loopCenterIdx); // 當(dāng)前項(xiàng) if (checkId === this.loopCenterIdx) { return; } if (checkId > this.loopCenterIdx) { if (this.loopCenterIdx === 0 && checkId === 4) { return this.handleLast(checkId); } else { return this.handleNext(checkId); } } if (checkId < this.loopCenterIdx) { if (checkId === 0 && this.loopCenterIdx === 4) { return this.handleNext(checkId); } else { return this.handleLast(checkId); } } }, }, }; </script>
js代碼里面有兩個(gè)地方需要注意的:
- 可以看到在上一張和下一張對(duì)應(yīng)的方法里面,有兩個(gè)一行代碼。其作用就是讓5個(gè)容器轉(zhuǎn)起來(lái)。
this.loopModules.unshift(this.loopModules.pop()); // [1,2,3,4] => [2,3,4,1] this.loopModules.push(this.loopModules.shift()); // [1,2,3,4] => [4,1,2,3]
- 在 handleLoop 方法中,需要注意展示項(xiàng)為 第一個(gè) 和 最后一個(gè) 的時(shí)候,和正常判斷邏輯相反。
后記
輪播作為一個(gè)日常開(kāi)發(fā)中最常見(jiàn)的組件,想必每一個(gè)前端都在學(xué)習(xí)js的時(shí)候?qū)⑺鳛橐粋€(gè)很有意思的 demo 練過(guò)手,而景深卡片輪播算是比基礎(chǔ)輪播稍微難一點(diǎn)的效果了。
這個(gè)組件值得記錄下來(lái)的是把數(shù)據(jù)驅(qū)動(dòng)視圖的思路更好的進(jìn)行了一次展示,這也是基于框架開(kāi)發(fā)和原生開(kāi)發(fā)的一個(gè)重要的轉(zhuǎn)變。如果在 jquery 中,可能會(huì)用 $(selector).animate() 去控制動(dòng)畫效果,原生 js 中也會(huì)封裝一個(gè)類似 animate() 的方式去逐幀的實(shí)現(xiàn)一系列的動(dòng)畫,而在 vue 中,直接修改數(shù)據(jù)的順序,或者修改數(shù)據(jù)值,就讓 dom 動(dòng)起來(lái)了。
數(shù)據(jù)驅(qū)動(dòng)視圖的思路下,我們就不必去關(guān)注視圖的變化,也不用頻繁的去操作dom元素,只需考慮清除一組可以控制視圖變化的鏈路就好了。例如:分頁(yè)組件只需要關(guān)注當(dāng)前頁(yè)碼和每頁(yè)顯示數(shù)量,表格組件只需要關(guān)注列數(shù)據(jù)的變化等等。其他的部分框架已經(jīng)做了很多。
路還很長(zhǎng),每走一步都有新感悟!
以上就是Vue組件實(shí)現(xiàn)景深卡片輪播示例的詳細(xì)內(nèi)容,更多關(guān)于Vue景深卡片輪播的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用vue-cli3+typescript的項(xiàng)目模板創(chuàng)建工程的教程
這篇文章主要介紹了使用vue-cli3+typescript的項(xiàng)目模板創(chuàng)建工程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02vue搜索頁(yè)開(kāi)發(fā)實(shí)例代碼詳解(熱門搜索,歷史搜索,淘寶接口演示)
這篇文章主要介紹了vue搜索頁(yè)開(kāi)發(fā)實(shí)例(熱門搜索,歷史搜索,淘寶接口演示),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04el-table實(shí)現(xiàn)轉(zhuǎn)置表格的示例代碼(行列互換)
這篇文章主要介紹了el-table實(shí)現(xiàn)轉(zhuǎn)置表格的示例代碼(行列互換),本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-02-02vue+highcharts實(shí)現(xiàn)3D餅圖效果
這篇文章主要為大家詳細(xì)介紹了vue+highcharts實(shí)現(xiàn)3D餅圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03在 vue-cli v3.0 中使用 SCSS/SASS的方法
關(guān)于如何在 vue-cli v3.0 中使用 SCSS/SASS,這里提供三種方案。感興趣的朋友通過(guò)本文一起學(xué)習(xí)吧2018-06-06VUE?Element修改el-input和el-select長(zhǎng)度的具體步驟
這篇文章主要給大家介紹了關(guān)于VUE?Element修改el-input和el-select長(zhǎng)度的具體步驟,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-12-12Vue?warn:Property?"state"?was?accessed?during
這篇文章主要為大家介紹了Vue?warn:Property?"state"?was?accessed?during?render的報(bào)錯(cuò)解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06