vue的滚动条插件实现代码


Posted in Javascript onSeptember 07, 2019

这篇文章主要介绍了vue的滚动条插件实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

效果如下

vue的滚动条插件实现代码

代码如下

<template>
  <div class="vue-scroll" ref="vueScrollW">
    <div class="vue-scroll-w" ref="vueScroll" >
      <div class="vue-scroll-c" :style="{width:cWidth}">
        <slot></slot>
      </div>
    </div>
    <div class="vue-scrollbar" v-if="rate < 1">
      <div class="vue-scrollbar-thumb"
      :style="{height:thumbH,top:thumbTop}"
      @mousedown="onmousedown"
      @mouseup="onmouseup"
      ></div>
    </div>
  </div>
</template>
 
<script>
 
 
 
export default {
  name:"vue-scroll",
  data(){
    return {
      thumb:0,
      top:0,
      rate:2,
      moveTop:null,
      isDrag:false,
      cw:10,
      observer:null
    }
  },
  computed:{
    thumbH(){
      return this.thumb + "px";
    },
    thumbTop(){
      return this.top + "px";
    },
    cWidth(){
      return this.cw + "%";
    }
    
  },
  updated(){
    if(!window.MutationObserver){
      this.refresh();
    }
  },
  mounted(){
    var me = this;
    me.$refs.vueScroll.addEventListener("scroll",me.onscroll.bind(me));
    window.addEventListener("mouseup",me.onmouseup.bind(me));
    window.addEventListener("mousemove",me.onmousemove.bind(me));
 
    if(window.MutationObserver){
      //MutationObserver 最低只兼容 ie11
      me.observer = new window.MutationObserver(me.mutationCallback.bind(me));
      me.observer.observe(me.$refs.vueScroll, {
        attributes: true,
        childList: true,
        subtree: true
      });
    }
    
    me.refresh();
  },
  methods:{
    mutationCallback(mutationsList){
      this.refresh();
    },
    onscroll(){
      this.top = this.$refs.vueScroll.scrollTop * this.rate; //计算滚动条所在的高度
      if(this.rate < 1){
        this.eventTrigger(this.top);
      }
    },
    refresh(){
      var me = this;
      var vueScroll = me.$refs.vueScroll;
      var rate = vueScroll.clientHeight / vueScroll.scrollHeight; //滚动条高度的比例,也是滚动条top位置的比例
      me.rate = rate;
      if(rate < 1){
        //需要出现滚动条,并计算滚动条的高度
        me.thumb = rate * vueScroll.clientHeight; //滚动条的 bar 的高度
        //计算出原生的滚动条的宽度
        var w = me.$refs.vueScrollW.clientWidth;
        //根据比例,转换为内容的百分比
        me.cw = w/vueScroll.clientWidth *100;
      }else{
        //不需要出现滚动条
         me.thumb = 0;
         me.cw = 10;
      }
    },
  
    onmousedown(){
      this.isDrag = true;
      this.moveTop = null;
    },
    onmouseup(){
      this.isDrag = false;
    },
    onmousemove(e){
      if(this.isDrag){
        if(this.moveTop !== null){
          var speed = e.screenY - this.moveTop;
          var top = this.top + speed;
          this.scrollThumb(top);
        }
        this.moveTop = e.screenY;
        e.preventDefault();
      }
       
    },
    scrollThumb(top){
      if(top < 0 ){
        top = 0;
         
      }
      if(top > this.$refs.vueScroll.clientHeight-this.thumb){
        top = this.$refs.vueScroll.clientHeight-this.thumb;
         
      }
       
      this.$refs.vueScroll.scrollTop = top/this.rate;
      this.top = top;
    },
    eventTrigger(top){
      if(top === 0){
        this.$emit("reachTop"); //到达顶部
      }
      if(top === this.$refs.vueScroll.clientHeight-this.thumb){
        this.$emit("reachBottom"); //到达底部与
      }
      this.$emit("vuescroll",this.$refs.vueScroll.scrollTop,this.top);//返回内容滚动的高度 和 滚动条所在的高度
    },
    scrollTo(scrollTop){
      //对外的api,滚动的内容的哪里
       this.$refs.vueScroll.scrollTop = scrollTop;
       this.$nextTick(()=>{
         this.onscroll();
       })
    }
  },
  destroyed(){
    var me = this;
    me.$refs.vueScroll && me.$refs.vueScroll.removeEventListener("scroll",me.onscroll.bind(me));
    window.removeEventListener("mouseup",me.onmouseup.bind(me));
    window.removeEventListener("mousemove",me.onmousemove.bind(me));
    me.observer&&me.observer.disconnect();
  }
}
</script>
 
<style lang="scss" scoped>
.vue-scroll{
  height: 100%;
  width: 100%;
  overflow: hidden;
  position: relative;
  .vue-scroll-w{
    width: 1000%;
    height: 100%;
    overflow: auto;
    .vue-scroll-c{
      position: relative;
      width: 10%;
    }
  }
  .vue-scrollbar{
    position: absolute;
    z-index: 1;
    right: 0;
    top: 0;
    width: 4px;
    height: 100%;
    background: #EEEEEE;
    opacity: 0.6;
    .vue-scrollbar-thumb{
      position: absolute;
      top: 0;
      right: 0;
      width: 4px;
      border-radius: 4px;
      background: #D3D3D3;
      &:hover{
        background: #bbb;
      }
      &:active{
        background: #aaa;
      }
    }
  }
}
</style>

使用

<template>
  <div class="scroll">
    <vueScroll>
      <ul>
        <li v-for="item in 60" :key="item">{{item}}</li>
      </ul>
    </vueScroll>
  </div>
</template>
 
<script>
import vueScroll from "@/components/vue-scroll.vue"
export default {
  data(){
    return {
      count:60
    }
  },
  components:{
    vueScroll
  },
  mounted(){
   
  }
}
</script>
<style lang="less" scoped>
.scroll{
  width: 400px;
  height: 600px;
  margin: 0 auto;
  border: 1px solid red;
  ul{
    li{
      line-height: 30px;
      border-bottom: 1px solid #ddd;
    }
  }
}
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript concat数组累加 示例
Sep 03 Javascript
Javascript排序算法之计数排序的实例
Apr 05 Javascript
基于jQuery实现仿淘宝套餐选择插件
Mar 04 Javascript
JavaScript事件委托实例分析
May 26 Javascript
jQuery中数据缓存$.data的用法及源码完全解析
Apr 29 Javascript
Web前端新人笔记之jquery入门心得(新手必看)
May 17 Javascript
JS简单实现无缝滚动效果实例
Aug 24 Javascript
Bootstrap CSS组件之大屏幕展播
Dec 17 Javascript
Webpack中publicPath路径问题详解
May 03 Javascript
vue超时计算的组件实例代码
Jul 09 Javascript
Vue的生命周期操作示例
Sep 17 Javascript
基于Vue 撸一个指令实现拖拽功能
Oct 09 Javascript
微信小程序页面滚动到指定位置代码实例
Sep 07 #Javascript
通过vue写一个瀑布流插件代码实例
Sep 07 #Javascript
javascript写一个ajax自动拦截并下载数据代码实例
Sep 07 #Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
Sep 06 #Javascript
解决layer.open后laydate失效的问题
Sep 06 #Javascript
layui的表单验证支持ajax判断用户名是否重复的实例
Sep 06 #Javascript
layui在form表单页面通过Validform加入简单验证的方法
Sep 06 #Javascript
You might like
一台收音机,让一家人都笑逐颜开!
2020/08/21 无线电
PHP的explode和implode的使用说明
2011/07/17 PHP
php $_SERVER windows系统与linux系统下的区别说明
2014/02/14 PHP
使弱类型的语言JavaScript变强势
2009/06/22 Javascript
javascript 学习笔记(一)DOM基本操作
2011/04/08 Javascript
JavaScript中for循环的使用详解
2015/06/03 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
JQuery Ajax WebService传递参数的简单实例
2016/11/02 Javascript
jQuery实现动态添加tr到table的方法
2016/12/26 Javascript
对象不支持indexOf属性或方法的解决方法(必看)
2017/05/28 Javascript
vue绑定设置属性的多种方式(5)
2017/08/16 Javascript
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
js获取html页面代码中图片地址的实现代码
2018/03/05 Javascript
Vue表单输入绑定的示例代码
2018/11/01 Javascript
解决layui使用layui-icon出现默认图标的问题
2019/09/11 Javascript
nodejs+express最简易的连接数据库的方法
2020/12/23 NodeJs
使用Python程序抓取新浪在国内的所有IP的教程
2015/05/04 Python
python过滤字符串中不属于指定集合中字符的类实例
2015/06/30 Python
python中的编码知识整理汇总
2016/01/26 Python
对numpy和pandas中数组的合并和拆分详解
2018/04/11 Python
python实现两个dict合并与计算操作示例
2019/07/01 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
Pytorch GPU显存充足却显示out of memory的解决方式
2020/01/13 Python
keras中的History对象用法
2020/06/19 Python
一个C/C++编程面试题
2013/11/10 面试题
什么是事务?为什么需要事务?
2012/01/09 面试题
大学生收银员求职信分享
2014/01/02 职场文书
洗煤厂厂长岗位职责
2014/01/03 职场文书
《美丽的小兴安岭》教学反思
2014/02/26 职场文书
幼儿教师培训感言
2014/03/08 职场文书
对祖国的寄语大全
2014/04/11 职场文书
驻村工作先进事迹
2014/08/14 职场文书
个人对照检查剖析材料
2014/10/13 职场文书
社区元宵节活动总结
2015/02/06 职场文书
浅谈由position属性引申的css进阶讨论
2021/05/25 HTML / CSS
使用Docker容器部署rocketmq单机的全过程
2022/04/03 Servers