基于vue封裝下拉刷新上拉加載組件
基于vue和原生javascript封裝的下拉刷新上拉加載組件,供大家參考,具體內(nèi)容如下
- upTilte插槽是下拉刷新的自定義內(nèi)容放的地方
- downTilte插槽是上拉加載的自定義內(nèi)容放的地方
- 默認(rèn)插槽為列表內(nèi)容區(qū)域
組件代碼如下
<template>
<div class="refresh" id="refresh">
<slot name="upTilte"></slot>
<slot></slot>
<slot name="downTilte"></slot>
</div>
</template>
<script>
export default {
name: 'PullupOrPulldownRefresh',
props: {
// 最大移動(dòng)距離
maxMove: {
type: Number,
default: 300
},
// 阻尼系數(shù)
friction: {
type: Number,
default: 0.3
}
},
data() {
return {
startY: 0,
ul: null,
draw: null,
up: null,
down: null,
y: 0 // 慣性回彈的距離
}
},
mounted() {
this.$nextTick(() => {
this.draw = document.getElementById('refresh')
this.ul = this.draw.children[1]
this.up = this.draw.children[0]
this.down = this.draw.children[2]
this.draw.addEventListener('touchstart', this.touchstart)
this.draw.addEventListener('touchmove', this.touchmoveEvent)
this.draw.addEventListener('touchend', this.touchendEvent)
})
},
methods: {
// 觸摸開始事件
touchstart(event) {
this.startY = event.changedTouches[0].clientY
},
// 觸摸移動(dòng)事件
touchmoveEvent(event) {
const height = this.ul.clientHeight - this.draw.clientHeight
if (height === this.draw.scrollTop || this.draw.scrollTop === 0) {
var a = event.changedTouches[0].clientY - this.startY
this.y = a <= this.maxMove ? a : this.maxMove
// 為了清除卡頓問題,需要清除過渡效果
this.ul.style.transition = 'none'
this.ul.style.transform = 'translateY(' + this.friction * this.y + 'px)'
// 修改狀態(tài)
const upHeight = -this.up.clientHeight + this.friction * this.y
// 下拉開始
if (this.friction * this.y > 0) (this.setStatus(this.friction * this.y), this.up.style.transition = 'none', this.up.style.transform = 'translateY(' + upHeight + 'px) translateX(-50%)')
// 上拉開始
if (this.friction * this.y < 0) (this.setStatus(this.friction * this.y), this.down.style.transition = 'none', this.down.style.marginTop = this.friction * this.y + 'px')
}
},
// 觸摸結(jié)束事件
touchendEvent(event) {
if (this.friction * this.y >= 50) this.$emit('RefreshUp', this.friction * this.y)
else if (this.friction * this.y < -50) this.$emit('RefreshDown', this.friction * this.y)
else this.resetStyle()
},
// 重置并且添加過渡效果
resetStyle() {
this.ul.style.transition = 'transform .6s'
this.ul.style.transform = 'translateY(' + 0 + 'px)'
this.up.style.transition = 'all .6s'
this.up.style.transform = 'translateY(-' + this.up.clientHeight + 'px) translateX(-50%)'
this.down.style.transition = 'all .6s'
this.down.style.marginTop = -this.down.clientHeight + 'px'
},
// 設(shè)置刷新狀態(tài)
setStatus(y) {
this.$emit('setStatus', y)
}
}
}
</script>
<style lang="scss">
.refresh {
width: 100%;
height: 100vh;
border: 2px solid #ccc;
position: relative;
overflow: hidden;
overflow: auto;
position: fixed;
ul {
zoom: 1;
padding: 0 10%;
}
ul::after {
content: '';
display: block;
visibility: hidden;
height: 0;
clear: both;
}
li {
list-style: none;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
}
.UpRefresh {
position: absolute;
left: 50%;
transform: translateX(-50%);
z-index: -9;
}
.DownRefresh {
position: relative;
left: 50%;
transform: translateX(-50%);
margin-top: -10px;
z-index: -9;
}
}
</style>
- 組件的使用方法
- friction為摩擦系數(shù)
- @RefreshUp為下拉到一定距離觸發(fā)事件
- @RefreshDown為上拉到一定距離觸發(fā)事件
- @setStatus為更改刷新狀態(tài)的方法
<template>
<div>
<PullupOrPulldownRefresh
ref="PullupOrPulldownRefresh"
:maxMove="maxMove"
:friction="friction"
@RefreshUp="RefreshUp"
@RefreshDown="RefreshDown"
@setStatus="setStatus"
>
<template v-slot:upTilte>
<!-- <div class="UpRefresh" v-show="isUpRefresh">{{ Uptitle }}</div> -->
<div class="UpRefresh" v-show="isUpRefresh">
<img :src="require('@/assets/logo.png')" alt="" />
<p>{{ Uptitle }}</p>
</div>
</template>
<ul>
<li
v-for="(item, index) in data"
:key="index"
style="background: orange"
>
{{ item }}
</li>
</ul>
<template v-slot:downTilte>
<div class="DownRefresh" v-show="isDownRefresh">{{ Downtitle }}</div>
</template>
</PullupOrPulldownRefresh>
</div>
</template>
<script>
export default {
data() {
return {
maxMove: 300,
friction: 0.3,
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
isUpRefresh: false,
isDownRefresh: false,
Downtitle: '上拉加載更多',
Uptitle: '下拉刷新'
}
},
methods: {
setStatus(y) {
if (y && y > 0) {
this.isUpRefresh = true
this.Uptitle = '下拉刷新'
if (y >= 50) this.Uptitle = '松手刷新'
return
}
this.isDownRefresh = true
this.Downtitle = '上拉加載更多'
if (y <= -50) this.Downtitle = '松手加載更多'
},
RefreshUp(y) {
if (!y) return
if (y >= 50) {
this.Uptitle = '正在刷新'
setTimeout(() => {
for (var i = 1; i <= 10; i++) {
this.data.push(this.data[this.data.length - 1] + 1)
}
this.$refs.PullupOrPulldownRefresh.resetStyle() // 回彈重置
}, 1000)
}
},
RefreshDown(y) {
if (!y) return
if (y <= -50) {
this.Downtitle = '正在加載'
setTimeout(() => {
for (var i = 1; i <= 10; i++) {
this.data.push(this.data[this.data.length - 1] + 1)
}
this.$refs.PullupOrPulldownRefresh.resetStyle() // 回彈重置
}, 1000)
}
}
}
}
</script>
<style scoped lang="scss">
.UpRefresh img{
width: 30px;
}
</style>
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
前端虛擬滾動(dòng)列表實(shí)現(xiàn)代碼(vue虛擬列表)
前端的性能瓶頸那就是頁面的卡頓,當(dāng)然這種頁面的卡頓包含了多種原因,下面這篇文章主要給大家介紹了關(guān)于前端虛擬滾動(dòng)列表實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06
使用mint-ui實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)效果的示例代碼
下面小編就為大家分享一篇使用mint-ui實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)效果的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-02-02
vue時(shí)間戳和時(shí)間的相互轉(zhuǎn)換方式
本文通過示例代碼介紹了vue時(shí)間戳和時(shí)間的相互轉(zhuǎn)換方式,通過場景分析介紹了vue3使用組合式api將時(shí)間戳格式轉(zhuǎn)換成時(shí)間格式(2023年09月28日 10:00),感興趣的朋友一起看看吧2023-12-12
Vue文件如何轉(zhuǎn)換成base64并去除多余的文件類型前綴
這篇文章主要介紹了Vue文件如何轉(zhuǎn)換成base64并去除多余的文件類型前綴問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
一文搞懂Vue3中的異步組件defineAsyncComponentAPI的用法
這篇文章主要介紹了一文搞懂Vue3中的異步組件,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07
Vue3+Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航的示例代碼
隨著單頁面應(yīng)用程序(SPA)的日益流行,前端開發(fā)逐漸向復(fù)雜且交互性強(qiáng)的方向發(fā)展,在這個(gè)過程中,Vue.js及其生態(tài)圈的工具(如Vue Router)為我們提供了強(qiáng)大的支持,本文將介紹如何在Vue 3中使用Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航,需要的朋友可以參考下2024-08-08

