better-scroll的封装实现回到顶部按钮

better-scroll的封装实现回到顶部按钮

话不多说先上效果:
better-scroll的封装实现回到顶部按钮

实现better-scroll封装之前,先了解better-scroll的使用初始化等操作【better-scroll初始化

better-scroll封装使用说明

scroll组件,将所需要滑动的部分通过插槽的方式传入better-scroll解构。
better-scroll封装使用
传入方式:
better-scroll的封装使用

better-scroll封装后的代码

注意:其中父组件传入的值是用来优化probeType的,因为有的不需要实时监听滚动,根据父组建的需要传入。
better-scroll封装后的代码

<template>
<div class="wrapper" ref="wrapper">
    <div class="content">
        <slot></slot>
    </div> 
</div>
</template>

<script>
import BScroll from '@better-scroll/core'
export default {
    
    
    props:{
    
    
        ProbeType:{
    
    
            type:Number,
            default:0
        }
    },
    data(){
    
    
        return{
    
    
            scroll:null
        }
    },
    mounted(){
    
    
        //创建BScroll对象
        this.scroll = new BScroll(this.$refs.wrapper,{
    
    
            probeType:this.probeType,//实时监听
            pullUpLoad: true,
            click:true,//点击有效
            observeDOM: true,
            mouseWheel:true
        })
        //2.监听滚动的位置
        this.scroll.on("scroll",(position)=>{
    
    
            //将position传出去
            this.$emit("scroll",position);
        })
    },
    methods:{
    
    
        scrollTo(x,y,time=300){
    
    
            this.scroll.scrollTo(x,y,time)
        }
    }
}
</script>

<style scoped>
</style>

父组件使用代码:

<scroll class="content" ref="scroll" :probe-type="3" @scroll="contentScroll">
                <swiper :imglink="banners"></swiper>
                <recommemd-view :recommends="recommends"></recommemd-view>
                <feature-view></feature-view>
                <tab-con-trol 
                        class="tabcontrol" 
                        :title="['流行','新款','精选']" 
                        @tabClick="tabClick">
                </tab-con-trol>
                <goods-list  :goods="showGoods"></goods-list>
        </scroll>

上面的父子组件调用的代码包含一些父子组件的通信知识
通过 this.$emit("scroll",position);将实时的滚动信息传给父组件,父组件通过ref="scroll"来接受子组件传递的scroll的position的信息,进行处理。

vue实现BackTop返回顶部按钮

实现思路
先将top按钮定义点击事件,位置通过flex定位定位到右下角,再使用v-show先进行隐藏TOP按钮默认v-show:"true",然后通过封装的scroll组件返回给父组件的position值,position的值是从scroll中获取到的当前滚动条距离顶部的距离,当滚动条达到一定条件的时候进行v-show:"true",将TOP按钮放到scroll组件局域的外部,思路可行,代码实现:
代码实现:
vue实现BackTop返回顶部按钮
data中的数据
vue实现BackTop返回顶部按钮
通过子组件将scroll的实时位置传递给父组件通过this.$emit("scroll",position);//自定义事件,加上值 传递,父组件通过ref="scroll"接受并通过"@"使用自定义事件@scroll="contentScroll"
将滚动内容放到scroll标签内

<scroll class="content" ref="scroll" :probe-type="3" @scroll="contentScroll">
...滚动内容...
</scroll>

引入知识点,ref是什么东西:

  1. ref如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件中的实例
  2. 可以通过实例直接调用组件的方法或访问数据,也算是子组件向父组件传值的一种。
$emit(event, args )
参数:
event:事件名、args:事件相关参数

用法:
触发当前实例上的事件。附加参数都会传给监听器回调。

注意:
在组件模板中:
不能直接通过 v-on 绑定触发 vue 实例中的方法,而需要先使用$emit( ) 绑定自定义事件,把自定义事件发射出去(发射到html 层面);
然后在html 层面:
组件自定义元素上,绑定自定义事件和vue 实例中的方法,以此实现组件和vue 实例方法的绑定。

@scroll="contentScroll"自定义事件,传过来的值position,根据position来来判断是否显示TOP按钮

		contentScroll(position){
    
    
            console.log(position.y);
            this.tabcontrol_xiding_logic = -position.y>533
            this.backtoplogic = -position.y>800
        },

better-scroll的封装实现回到顶部按钮
实现效果:better-scroll的封装实现回到顶部按钮
存留问题,回到顶部的按钮点击后回到顶部的速度太快,使用better-scroll自带的方法可进行返回顶部的时间设置

 	methods:{
    
    
        scrollTo(x,y,time=300){
    
    
            this.scroll.scrollTo(x,y,time)
        }
    }

父组件调用该代码使用了$refs进行直接调用子组件的方法:

		backtopclick(){
    
    
           this.$refs.scroll.scrollTo(0,0,500)
        },

当然,better-scroll使用后,吸顶效果也会失效,创建另一个吸顶效果的HTML代码放到scroll局域的外面,通过data定义的变量进行判断是否显示,实现方法也是如此。

上面总结的如果比较乱,那么完全代码如下:
Home.vue【父组件】代码

<template>
    <div id="home">
        <nav-bar class="home-nav"><div slot="center">购物街</div></nav-bar>
        <!-- <div class="wrapper">
            <div class="content">
                <swiper :imglink="banners"></swiper>
                <recommemd-view :recommends="recommends"></recommemd-view>
                <feature-view></feature-view>
                <tab-con-trol 
                        class="tabcontrol" 
                        :title="['流行','新款','精选']" 
                        @tabClick="tabClick">
                </tab-con-trol>
                <goods-list  :goods="showGoods"></goods-list>
            </div>
        </div> -->
        <scroll class="content" ref="scroll" :probe-type="3" @scroll="contentScroll">
                <swiper :imglink="banners"></swiper>
                <recommemd-view :recommends="recommends"></recommemd-view>
                <feature-view></feature-view>
                <tab-con-trol 
                        class="tabcontrol" 
                        :title="['流行','新款','精选']" 
                        @tabClick="tabClick">
                </tab-con-trol>
                <goods-list  :goods="showGoods"></goods-list>
        </scroll>
        <tab-con-trol 
                class="tabcontrol_xiding" 
                :title="['流行','新款','精选']" 
                @tabClick="tabClick" v-show="tabcontrol_xiding_logic">
        </tab-con-trol>
        <back-top class="backtop" @click.native="backtopclick" v-show="backtoplogic"></back-top>

        
        <ul>
            li{
    
    第$个li}*1000    
        </ul>
    </div>
</template>

<script>
  import NavBar from "components/common/Homenavbar/NavBar.vue";
  import Swiper from 'components/common/swiper/swiper'
  import RecommemdView from 'components/common/HomerecommendView/recommendview.vue'
  import FeatureView from "components/common/HomefeatureView/feature.vue"
  import Scroll from 'components/common/scroll/scroll.vue'   

  import TabConTrol from "components/content/TabControl/tabcontrol.vue"
  import GoodsList from "components/content/goods/GoodsList.vue"
  import BackTop from "components/content/BackTop/BackTop.vue"

  import {
    
    getHomeMultidata,getHomeGoods} from "network/home";
  export default {
    
    
      name:"Home",
      data(){
    
    
          return {
    
    
              banners:[],
              recommends:[],
              goods:{
    
    
                "pop":{
    
    page:0,list:[]},
                "new":{
    
    page:0,list:[]},
                "sell":{
    
    page:0,list:[]},
              },
              currentType:"pop",
              tabcontrol_xiding_logic:false,
              backtoplogic:false,
              
          }
      },
      computed:{
    
    
          showGoods(){
    
    
              return this.goods[this.currentType].list
          }
      },
      components:{
    
    
        NavBar,
        Swiper,
        RecommemdView,
        FeatureView,
        TabConTrol,
        GoodsList,
        Scroll,
        BackTop,
     },
    created(){
    
    
        //1.请求多个数据
        this.getHomeMultidata();
        
        //请求“新款”,“流行”,“精选”的商品数据
        this.getHomeGoods('pop');
        this.getHomeGoods('new');
        this.getHomeGoods('sell');

    },
    methods:{
    
    
        /**
         * 事件监听相关的方法
         */        
        tabClick(index){
    
    
            switch(index){
    
    
                case 0:
                    this.currentType = "pop";
                    break;
                case 1:
                    this.currentType = "new";
                    break;
                case 2:
                    this.currentType = "sell";
                    break;
            }
            console.log(index);
        },
        backtopclick(){
    
    
           this.$refs.scroll.scrollTo(0,0,500)
        },
        contentScroll(position){
    
    
            console.log(position.y);
            this.tabcontrol_xiding_logic = -position.y>533
            this.backtoplogic = -position.y>800
        },
        /**
         * 网络请求相关方法
         */
        getHomeMultidata(){
    
    
            getHomeMultidata().then(res=>{
    
    
                this.banners = res.data.data.banner.list;
                this.recommends = res.data.data.recommend.list;
            })
        },
        getHomeGoods(type){
    
    
            const page = this.goods[type].page + 1;
            getHomeGoods(type,page).then(res=>{
    
    
                this.goods[type].list.push(...(res.data.data.list));                
                this.goods[type].page += 1
            })
        },
  }
}
</script>

<style scoped>
#home{
    
    
    padding-top:44px;
    height: 100vh;
    position: relative;
}
.home-nav{
    
    
    background-color: var(--color-tint);
    color: white;
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    z-index: 9;
}
.tabcontrol{
    
    
    background-color: white;
    /* position: sticky; 
    top: 44px; */
    z-index: 999;
}
.tabcontrol_xiding{
    
    
    background-color: white;
   position: absolute;
  top: 44px;
  width: 100%;
}
.content{
    
    
    height:calc(100vh - 93px);
    overflow: hidden;
    padding-bottom: 10px;
}
.backtop{
    
    
    z-index: 100000;
}
</style>  

scroll.vue【子组件】代码:封装代码

<template>
<div class="wrapper" ref="wrapper">
    <div class="content">
        <slot></slot>
    </div> 
</div>
</template>

<script>
import BScroll from '@better-scroll/core'
export default {
    
    
    props:{
    
    
        ProbeType:{
    
    
            type:Number,
            default:0
        }
    },
    data(){
    
    
        return{
    
    
            scroll:null
        }
    },
    mounted(){
    
    
        //创建BScroll对象
        this.scroll = new BScroll(this.$refs.wrapper,{
    
    
            probeType:this.probeType,//实时监听
            pullUpLoad: true,
            click:true,//点击有效
            observeDOM: true,
            mouseWheel:true
        })
        //2.监听滚动的位置
        this.scroll.on("scroll",(position)=>{
    
    
            //将position传出去
            this.$emit("scroll",position);
        })
    },
    methods:{
    
    
        scrollTo(x,y,time=300){
    
    
            this.scroll.scrollTo(x,y,time)
        }
    }
}
</script>

<style scoped>
</style>

最终效果:
better-scroll的封装实现回到顶部按钮和吸顶按钮

猜你喜欢

转载自blog.csdn.net/qq_42696432/article/details/121915474
今日推荐