Advantages of this component:
1, use small program/UNIApp native page slide, fluency is higher than scroll view component 2, use component directly, 3, including no data spatio-temporal layout display 4, can customize the drop-down refresh, drop-down loading style 5, the two-way binding of components V-Model 6, perfect solution to the custom navigation can not see the drop-down refresh loading problem
Actual renderings
We turned it on in page.jsonCustom navigation barProperties andThe drop-down refreshAfter the attributes
// Enable pull-down refresh
"enablePullDownRefresh": true
// Customize the navigation bar
"navigationStyle": "custom"
Copy the code
At this point, the three dots in the drop-down refresh of the page will be covered by our navigation bar, so that users cannot see the loading effect in the drop-down refresh, as shown in the following figure
So the user experience is not good. Let’s see how to solve this problem:
1. Encapsulate the MScroll component
2. Encapsulate componentsThe drop-down refresh,Pull on loading,When loading is completemethods
3, the use ofmargin-top: -100upx;
Hide the loading we wrote before the user pulls down the refresh
Encapsulates the MScroll component
<template>
<div class="mscroll">
<! -- Drop down to refresh -->
<div class="loading pullLoading">
<i class="dot"></i>
</div>
<! -- Content slot -->
<slot/>
<! -- Pull load -->
<div v-if="hasNextPage" class="loading">
<i class="dot"></i>
</div>
<! -- Empty layout -->
<div class="empty" v-if='isEmpty'>
<! -- Change the picture yourself -->
<img mode='widthFix' src=".. /.. /assets/image/logoPng.png" alt="">
<p>There is nothing here ~</p>
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: Object.required: true.default () {
return {
// Current page number
page: 1.// Number of entries per page
pageSize: 10.// Is there a next page
hasNextPage: false.// Total number of data
total: 0
}
}
}
},
data () {
return {
/ / the next page
hasNextPage: false./ / no data
isEmpty: false./ / load
isLoading: false}},computed: {
// Convert pages
pages () {
return this.value
}
},
methods: {
// Drop refresh
pullRefresh () {
/ / load
this.isLoading = true
this.$emit('input', {... this.pages,page: 1})
this.$emit('getData')},// Pull up load
loadMore () {
// There is no next page or loading is not loaded
if (!this.hasNextPage || this.isLoading) return
/ / load
this.isLoading = true
this.$emit('input', {... this.pages,page: this.pages.page + 1})
this.$emit('getData')},// Successfully loaded method
loadSuccess (data) {
// The first page should go back to the top
if (data.page == 1) {
uni.pageScrollTo({
scrollTop: 0})}// End of the drop-down refresh
uni.stopPullDownRefresh()
// Close the load
this.isLoading = false
// Whether there is a next page (can be determined by the total number of pages and current page)
this.hasNextPage = data.hasNextPage
// Whether there is data
this.isEmpty = ! data.total } } }</script>
<style lang='scss' scoped>// Load the animation@keyframes dotFlashing {
0% {
background-color: #ccc;
}
100% {
background-color: # 999; }}.mscroll{
// loading
.loading {
display: flex;
justify-content: center;
align-items: center;
height: 100upx;
overflow: hidden;
&.pullLoading{// here is the keymargin-top: -100upx; } // Simulate wechat dot.dot {
display: inline-block;
position: relative;
width: 14upx;
height: 14upx;
border-radius: 50%;
background: # 999;
animation: dotFlashing 1s infinite linear alternate;
animation-delay:.5s;
&::before {
left: -28upx;
animation: dotFlashing 1s infinite alternate;
animation-delay: 0s;
}
&::after {
left: 28upx;
animation: dotFlashing 1s infinite alternate;
animation-delay: 1s;
}
&::before,
&::after {
content: ' ';
display: inline-block;
position: absolute;
top: 0;
width: 14upx;
height: 14upx;
border-radius: 50%;
background: # 999; }}} // Empty layout.empty{
margin-top: 280upx;
text-align: center;
img{
width: 180upx;
}
p{
margin-top: 20upx;
color: # 999;
font-size: 26upx
}
}
}
</style>
Copy the code
use
Page. Json configuration
"pages": [{"path": "pages/homePage/index"."style": {
"navigationBarTitleText": "Page title".// Page title
"enablePullDownRefresh": true.// Enable drop-down refresh (required)
"backgroundTextStyle": "light".// Pull down refresh loading small dot color, white background + white small dot can realize "hide" native small dot oh
"navigationStyle": "custom".// Customize the navigation bar (you can also use this component without customizing the navigation bar, but you can only use the native dot style, you cannot customize the drop-down refresh style)
"backgroundColor": "#F5F7F9" // Page background color}}]Copy the code
Parent component use
<template> <! Calculate your navigation altitude --><div class='index' :style="{'padding-top': '100px'}">
<! -- Custom navigation bar -->
<nav :style="{height: '100px'}"></nav>
<! Pages = pages -->
<m-scroll ref='mscroll' v-model="pages" @getData='getData'>
<! -- List data -->
<ul>
<li v-for="i in list" :key="i">Analog data ------------- section {{I + 1}}</li>
</ul>
</m-scroll>
</div>
</template>
<script>
import mScroll from './mscroll'
export default {
components: {
mScroll
},
data () {
return {
list: 20.pages: {
page: 1.pageSize: 10}}},// Triggers a pull-down refresh
onPullDownRefresh () {
this.$refs.mscroll.pullRefresh()
},
// Triggers pull-up loading
onReachBottom () {
this.$refs.mscroll.loadMore()
},
onLoad () {
this.getData()
},
methods: {
getData () {
// simulate the request
setTimeout(() = > {
this.list += 10
const total = 50
consthasNextPage = total ! =this.list
const data = {
page: this.pages.page, // Page number must be included
total, // The total number must be included
hasNextPage // The next page must be included
}
// The current page number, total data, and next page are required
this.$refs.mscroll.loadSuccess(data)
}, 1000)}}}</script>
<style lang='scss' scoped>// Customize the navigation barnav{
background: #446AAD;
position: fixed;
z-index: 10;
left: 0;
top: 0;
right: 0;
}
ul{
li{
padding: 20upx;
border-bottom: 1px solid #eee; }}</style>
Copy the code
At this point, the code is finished, considering or have a bug place, but also hope a lot of messages to inform me 😁!