Vue?仿QQ左滑刪除組件功能
前幾天在做Vue項(xiàng)目開發(fā)的時(shí)候,因?yàn)橹皠e人寫的代碼有點(diǎn)小 bug,有人反應(yīng) IOS 上面的滑動(dòng)點(diǎn)擊有點(diǎn)問題,于是讓我來幫忙解決,我看了看以前的代碼實(shí)現(xiàn)比較繁瑣,冗余,索性就直接自己重新寫了一套,供大家參考,如有更好的方式,歡迎及時(shí)交流~
我們先看看效果圖吧,畢竟無圖無真相啊~
效果圖
實(shí)現(xiàn)思路
具體實(shí)現(xiàn)思路如下:
- 布局方面我采用的是 rem + flex 布局,具體如何結(jié)構(gòu)和樣式可以參考我的代碼,值得注意的是后面的刪除按鈕是我通過定位放在了每一行的最后,超出隱藏了而已
- 左滑和右滑是通過 touchstart 和 touchend 事件,通過判斷滑動(dòng)開始和結(jié)束,水平方向 x 的偏移量,如果大于一定得閾值認(rèn)為是左滑動(dòng),小于一定的閾值則認(rèn)為是右滑動(dòng)
- 左滑動(dòng)和右滑動(dòng)分別都是通過父級(jí) li 元素的 translate 偏移量進(jìn)行變化的,這里我的實(shí)現(xiàn)方式是提前聲明好樣式,通過改變當(dāng)前父級(jí) li 的 type 值,進(jìn)行樣式切換
- 點(diǎn)擊某一個(gè)滑塊的時(shí)候,首先判斷當(dāng)前所有的滑塊是否有處于 滑出狀態(tài)的 ,如果有,則必須先將所有的滑塊狀態(tài)還原,如果沒有,則點(diǎn)擊生效,我這里只是彈出一個(gè) alter ,具體業(yè)務(wù)可以根據(jù)實(shí)際填寫
- 刪除相對簡單,當(dāng)滑塊畫出后,出現(xiàn)刪除按鈕,點(diǎn)擊按鈕,拿到當(dāng)前的數(shù)組索引值,通過數(shù)組的 splice 方法,刪除對應(yīng)的數(shù)組值即可
具體實(shí)現(xiàn)
Html代碼
<div class="container"> <div class="page-title">滑動(dòng)組件</div> <ul> <li class="list-item " v-for="(item,index) in list " data-type="0"> <div class="list-box" @touchstart.capture="touchStart" @touchend.capture="touchEnd" @click="skip"> <img class="list-img" :src="item.imgUrl" alt=""> <div class="list-content"> <p class="title">{{item.title}}</p> <p class="tips">{{item.tips}}</p> <p class="time">{{item.time}}</p> </div> </div> <div class="delete" @click="deleteItem" :data-index="index">刪除</div> </li> </ul> </div>
注意:我這里的數(shù)據(jù)全是本地 mock 的~
Css樣式代碼
.page-title{ text-align: center; font-size: 17px; padding: 10px 15px; position: relative; } .page-title:after{ content: " "; position: absolute; left: 0; bottom: 0; right: 0; height: 1px; border-bottom: 1px solid #ccc; color: #ccc; -webkit-transform-origin: 0 100%; transform-origin: 0 100%; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); z-index: 2; } .list-item{ position: relative; height: 1.6rem; -webkit-transition: all 0.2s; transition: all 0.2s; } .list-item[data-type="0"]{ transform: translate3d(0,0,0); } .list-item[data-type="1"]{ transform: translate3d(-2rem,0,0); } .list-item:after{ content: " "; position: absolute; left: 0.2rem; bottom: 0; right: 0; height: 1px; border-bottom: 1px solid #ccc; color: #ccc; -webkit-transform-origin: 0 100%; transform-origin: 0 100%; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); z-index: 2; } .list-box{ padding: 0.2rem; background: #fff; display: flex; align-items: center; -webkit-box-sizing: border-box; box-sizing: border-box; justify-content: flex-end; position: absolute; top: 0; right: 0; bottom: 0; left: 0; font-size: 0; } .list-item .list-img{ display: block; width: 1rem; height: 1rem; } .list-item .list-content{ padding: 0.1rem 0 0.1rem 0.2rem; position: relative; flex: 1; flex-direction: column; align-items: flex-start; justify-content: center; overflow: hidden; } .list-item .title{ display: block; color: #333; overflow: hidden; font-size: 15px; font-weight: bold; text-overflow: ellipsis; white-space: nowrap; } .list-item .tips{ display: block; overflow: hidden; font-size: 12px; color: #999; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; } .list-item .time{ display: block; font-size: 12px; position: absolute; right: 0; top: 0.1rem; color: #666; } .list-item .delete{ width: 2rem; height: 1.6rem; background: #ff4949; font-size: 17px; color: #fff; text-align: center; line-height: 1.6rem; position: absolute; top:0; right: -2rem; }
這是核心的樣式代碼,還有部分樣式重置代碼放在了 App.vue 里,通過計(jì)算根節(jié)點(diǎn) html 的字體大小的腳本我放在了 index.html 中~
js代碼
export default{ name: 'index', data () { return { list : [ { title : 'Chrome更新了' , imgUrl : './static/images/Chrome.png' , tips : '不再支持Flash視頻播放' , time : '上午 8:30' }, { title : '電影新資訊' , imgUrl : './static/images/Sina.png' , tips : '電影《紅海行動(dòng)》上映以來票房暴漲,很多國人表示對國產(chǎn)電影有了新的改觀' , time : '上午 12:00' }, }, methods : { //跳轉(zhuǎn) skip(){ if( this.checkSlide() ){ this.restSlide(); }else{ alert('You click the slide!') } }, //滑動(dòng)開始 touchStart(e){ // 記錄初始位置 this.startX = e.touches[0].clientX; }, //滑動(dòng)結(jié)束 touchEnd(e){ // 當(dāng)前滑動(dòng)的父級(jí)元素 let parentElement = e.currentTarget.parentElement; // 記錄結(jié)束位置 this.endX = e.changedTouches[0].clientX; // 左滑 if( parentElement.dataset.type == 0 && this.startX - this.endX > 30 ){ this.restSlide(); parentElement.dataset.type = 1; } // 右滑 if( parentElement.dataset.type == 1 && this.startX - this.endX < -30 ){ this.restSlide(); parentElement.dataset.type = 0; } this.startX = 0; this.endX = 0; }, //判斷當(dāng)前是否有滑塊處于滑動(dòng)狀態(tài) checkSlide(){ let listItems = document.querySelectorAll('.list-item'); for( let i = 0 ; i < listItems.length ; i++){ if( listItems[i].dataset.type == 1 ) { return true; } } return false; }, //復(fù)位滑動(dòng)狀態(tài) restSlide(){ let listItems = document.querySelectorAll('.list-item'); // 復(fù)位 for( let i = 0 ; i < listItems.length ; i++){ listItems[i].dataset.type = 0; } }, //刪除 deleteItem(e){ // 當(dāng)前索引 let index = e.currentTarget.dataset.index; // 復(fù)位 this.restSlide(); // 刪除 this.list.splice(index,1); } } }
js代碼就這么一些,每個(gè)函數(shù)都有注釋說明, 相信都能看得懂, 就不多解釋了。
結(jié)語
怎么樣,是不是也米有想象中的那么難,只要理清思路即可,實(shí)現(xiàn)起來也并不是那么困難,當(dāng)然我這里寫的只是我的一個(gè)實(shí)現(xiàn)思路而已,可能你們自己會(huì)有更好的實(shí)現(xiàn)方式,為什么不拿出來分享呢?
完整代碼我已經(jīng)托管到 gitlub 上了,歡迎下載使用并留言!
相關(guān)文章
vue中eslint導(dǎo)致的報(bào)錯(cuò)問題及解決
這篇文章主要介紹了vue中eslint導(dǎo)致的報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10解決vue項(xiàng)目Error:Cannot find module‘xxx’類報(bào)錯(cuò)問題
當(dāng)npm運(yùn)行報(bào)錯(cuò)Error:Cannot find module 'xxx'時(shí),通常是因?yàn)閚ode_modules文件或依賴未正確安裝,解決步驟包括刪除node_modules和package-lock.json文件,重新運(yùn)行npm install,并根據(jù)需要安裝額外插件,若網(wǎng)絡(luò)問題導(dǎo)致安裝失敗2024-10-10vue項(xiàng)目上傳Github預(yù)覽的實(shí)現(xiàn)示例
這篇文章主要介紹了vue項(xiàng)目上傳Github預(yù)覽的實(shí)現(xiàn)示例,在完成Vue項(xiàng)目以后,在上傳到github并實(shí)現(xiàn)預(yù)覽2018-11-11vue+Element-ui實(shí)現(xiàn)分頁效果實(shí)例代碼詳解
這篇文章主要介紹了vue+Element-ui實(shí)現(xiàn)分頁效果 ,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12VUE利用vuex模擬實(shí)現(xiàn)新聞點(diǎn)贊功能實(shí)例
本篇文章主要介紹了VUE利用vuex模擬實(shí)現(xiàn)新聞點(diǎn)贊功能實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解
這篇文章主要為大家介紹了Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02