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 相关文章推荐
JS 实现图片直接下载示例代码
Jul 22 Javascript
浅谈jQuery中setInterval()方法
Jul 07 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
Aug 27 Javascript
jQuery 限制输入字符串长度
Jun 20 Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
Aug 25 Javascript
javascript设置文本框光标的方法实例小结
Nov 04 Javascript
Vuejs仿网易云音乐实现听歌及搜索功能
Mar 30 Javascript
详解js的作用域、预解析机制
Feb 05 Javascript
详解微信小程序框架wepy踩坑记录(与vue对比)
Mar 12 Javascript
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
May 16 Javascript
深入理解基于vue-cli的webpack打包优化实践及探索
Oct 14 Javascript
vue 监听窗口变化对页面部分元素重新渲染操作
Jul 28 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
九个你必须知道而且又很好用的php函数和特点
2013/08/08 PHP
CodeIgniter CLI模式简介
2014/06/17 PHP
PHP之autoload运行机制实例分析
2014/08/28 PHP
php中动态变量用法实例
2015/06/10 PHP
PHP数据源架构模式之表入口模式实例分析
2020/01/23 PHP
9个JavaScript评级/投票插件
2010/01/18 Javascript
基于jquery的复制网页内容到WORD的实现代码
2011/02/16 Javascript
实现只能输入数字的input不用replace方法
2013/09/12 Javascript
基于JavaScript如何制作遮罩层对话框
2016/01/26 Javascript
Angular实现form自动布局
2016/01/28 Javascript
使用jQuery判断Div是否在可视区域的方法 判断div是否可见
2016/02/17 Javascript
Nodejs中的JWT和Session的使用
2018/08/21 NodeJs
Vue高版本中一些新特性的使用详解
2018/09/25 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
Python SQL查询并生成json文件操作示例
2018/08/17 Python
Python模拟简单电梯调度算法示例
2018/08/20 Python
Python使用paramiko操作linux的方法讲解
2019/02/25 Python
wxPython实现列表增删改查功能
2019/11/19 Python
Pytorch GPU显存充足却显示out of memory的解决方式
2020/01/13 Python
python orm 框架中sqlalchemy用法实例详解
2020/02/02 Python
浅谈Python线程的同步互斥与死锁
2020/03/22 Python
Python中logger日志模块详解
2020/08/04 Python
详解如何解决canvas图片getImageData,toDataURL跨域问题
2018/09/17 HTML / CSS
美国专业级皮肤病和spa品质护肤品的高级零售网站:SkinCareRx
2017/02/06 全球购物
巴基斯坦电子产品购物网站:Home Shopping
2017/09/14 全球购物
英国领先的在线高尔夫商店:Gamola Golf
2019/11/16 全球购物
材料加工硕士生求职信
2013/10/10 职场文书
行政部工作岗位职责范本
2014/03/05 职场文书
分层教学实施方案
2014/03/19 职场文书
简单通用的简历自我评价
2014/09/21 职场文书
2014年国庆节演讲稿精选范文1500字
2014/09/25 职场文书
2015公务员试用期工作总结
2014/12/12 职场文书
春节慰问信范文
2015/02/15 职场文书
2016大学军训通讯稿
2015/11/25 职场文书
2016年七夕爱情寄语
2015/12/04 职场文书
MySQL系列之十二 备份与恢复
2021/07/02 MySQL