基于Vuescroll.js封装上拉加载、下拉刷新组件实际应用开发

什么是 vuescroll

摘自官网描述:vuescroll 是一款基于 Vue.js 自定义滚动条的插件,它有两种模式: native: 适用于 PC 端,支持基本的自定义滚动条。 slide: 适用于移动端, 支持下拉-加载,上拉刷新,轮播等。 但是,这并不意味着 slide模式只能用于移动端,只是因为移动端与 slide 模式更加契合而已。废话不多说,直接上代码

安装

npm install vuescroll --save

全局注册

// **main.js**
import Vue from 'vue';
import vuescroll from 'vuescroll';

// 你可以在这里设置全局配置
Vue.use(vuescroll, {
  ops: {}, // 在这里设置全局默认配置
  name: 'myScroll' // 在这里自定义组件名字,默认是vueScroll
});
/*
 * 或者
 */
Vue.use(vuescroll); // install the vuescroll first
Vue.prototype.$vuescrollConfig = {
  bar: {
    background: '#000'
  }
};

局部注册

<template>
  <vuescroll> <!-- 你的内容... --> </vuescroll>
</template>
<script>
  import vuescroll from 'vuescroll';

  export default {
    components: {
      vuescroll
    }
  };
</script>

本地封装vue-scroll.vue组件

<template>
    <div class="pr-wrap">
        <div class="wrap-part first">
            <vuescroll
                ref="vs"
                :ops="ops"
                @refresh-start="handleRS"
                @load-before-deactivate="handleLBD"
                @refresh-before-deactivate="handleRBD"
                @load-start="handleLoadStart"
            >
                <slot></slot>
                <div slot="load-beforeDeactive" v-if="noData">
                    <svg
                        viewBox="0 0 1024 1024"
                        version="1.1"
                        xmlns="http://www.w3.org/2000/svg"
                        p-id="8056"
                    >
                        <path
                        d="M469.333333 384h85.333334v213.333333h-85.333334z m0 298.666667h85.333334v85.333333h-85.333334z"
                        fill=""
                        p-id="8057"
                        ></path>
                        <path
                        d="M549.717333 108.032c-14.762667-27.904-60.672-27.904-75.434666 0l-384 725.333333A42.624 42.624 0 0 0 128 896h768a42.581333 42.581333 0 0 0 37.674667-62.592L549.717333 108.032zM198.869333 810.666667L512 219.221333 825.130667 810.666667H198.869333z"
                        fill=""
                        p-id="8058"
                        ></path>
                    </svg>
                    {{lang == 'zh' ? '暂无更多': 'No More Data'}}
                </div>
            </vuescroll>
        </div>
    </div>
</template>

<script>
import vuescroll from 'vuescroll';
export default {
    props: {
        // 语言
        lang: {
            default: 'zh' // en 
        },
        // 距离底部触发自动加载的距离
        autoLoadDistance:{
            default: 10
        },
        // 是否开启下拉刷新
        isRefresh:{
            default: true
        },
        // 是否开启上拉加载
        isPushLoad:{
            default: true
        },
        // 数据是否全部加载完成 true为全部加载完成
        noData:{
            default: false
        },
        // 下拉刷新开始
        refreshStart:{
            default:()=>{}
        },
        // 下拉刷新完成之后
        refreshDeactivate:{
            default:()=>{}
        },
        // 上拉开始
        loadStart:{
            default:()=>{}
        },
        // 上拉完成之后
        loadDeactivate:{
            default:()=>{}
        }
    },
    components:{vuescroll},
    data() {
        const config = {};
        const ops = {
            vuescroll: {
                mode: 'slide',
                pullRefresh: {
                    enable: this.isRefresh
                },
                pushLoad: {
                    enable: this.isPushLoad,
                    auto: true, //是否自动触发加载
                    autoLoadDistance: this.autoLoadDistance 
                }
            }
        };
        if (this.lang == 'zh') {
            ops.vuescroll.pullRefresh.tips = {
                deactive: '下拉刷新',
                active: '释放刷新',
                start: '刷新中...',
                beforeDeactive: '刷新成功!'
            };
            ops.vuescroll.pushLoad.tips = {
                deactive: '上拉加载',
                active: '释放加载',
                start: '加载中...',
                beforeDeactive: '加载成功!'
            };
        }
        return {
            ops,
            config
        };
    },
    methods: {
        
        // 刷新开始
        // vsInstance vm===this
        // refreshDom === 刷新dom 
        handleRS(vsInstance, refreshDom, done) {
            if(this.refreshStart){
                this.refreshStart(done)
            }else{
                this.setDone(done)
            }
        },
        // 刷新完之后
        handleRBD(vm, loadDom, done) {
            if(this.refreshDeactivate){
                this.refreshDeactivate(done)
            }else{
                setTimeout(()=>{
                    this.setDone(done)
                },600)
            }    
        },
        // 上拉开始
        handleLoadStart(vm, dom, done) {
            if(this.loadStart){
                this.loadStart(done)
            }else{
                this.setDone(done)
            }    
        },
        // 上拉完成后
        handleLBD(vm, loadDom, done) {
            if (!this.$parent.noData) {
                if(this.loadDeactivate){
                    this.loadDeactivate(done)
                }else{
                    setTimeout(()=>{
                        this.setDone(done)
                    },600)
                }
            }else{
                setTimeout(()=>{
                    this.setDone(done)
                },600)
            }
        },
        // 手动触发 外部通过ref触发
        // type load 为加载   refresh 为刷新
        trigger(type='load') {
            this.$refs['vs'].triggerRefreshOrLoad(type);
        },
        setDone(done){
            done()
        }
      }
};
</script>

<style lang="less" scoped>
    .pr-wrap {
        display: flex;
        height: 100%;
        justify-content: center;
        width: 100%;
        .wrap-part {
            height: 100%;
            &.first {
                width: 100%;
            }
        }
    }
</style>

在test.vue 中使用

<template>
    <div class="test">
        <vue-scroll
            :refreshStart='refreshStart'
            :loadStart='loadStart'
            :noData='noData'
        >
            <div class="rl-child child1"></div>
            <div class="rl-child child2"></div>
            <div class="rl-child child3"></div>
        </vue-scroll>
    </div>
</template>

<script>
export default {
    data(){
        return {
            noData:false //判断是否数据全部加载完成 true为全部加载完
        }
    },
    methods:{
        // 刷新开始
        refreshStart(done){
            setTimeout(()=>{
                // 这里写 ajax 业务请求,在数据请求到后执行 done() 关闭动画
                done() 
            },1600)
        },
        // 加载开始
        loadStart(done){
            setTimeout(()=>{
                // 这里写 ajax 业务请求,在数据请求到后执行 done() 关闭动画
                done() 
            },1600)
        }
    }
}
</script>

<style lang="less" scoped>
    .rl-child {
        width: 100%;
        height: 500px;
    }
    .child1 {
        width: 100%;
        height: 500px;
        background-color: #43d2c6;
    }
    .child2 {
        background-color: #589be5;
    }
    .child3 {
        background-color: #f3b500;
    }
</style>

完成效果-测试-以及在实际项目钟使用

图片描述图片描述

阅读 1.9k

推荐阅读
vipbic
用户专栏

vipbic是一个关注前端开发、网址导航、学习视屏免费下载、HTML5、CSS3、JavaScript、PHP的前端杨航开发...

24 人关注
29 篇文章
专栏主页
目录