基于Vuescrolljs封装上拉加载下拉刷新组件实际应用开发

58次阅读

共计 3932 个字符,预计需要花费 10 分钟才能阅读完成。

什么是 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>

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

正文完
 0