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入门教程(8) Location地址对象
Jan 31 Javascript
浅析hasOwnProperty方法的应用
Nov 20 Javascript
javascript制作坦克大战全纪录(2)
Nov 27 Javascript
js电话号码验证方法
Sep 28 Javascript
如何实现移动端浏览器不显示 pc 端的广告
Oct 15 Javascript
JavaScript判断用户名和密码不能为空的实现代码
May 16 Javascript
jquery 实时监听输入框值变化的完美方法(必看)
Jan 26 Javascript
JavaScript基础之流程控制语句的用法
Aug 31 Javascript
vue-cli系列之vue-cli-service整体架构浅析
Jan 14 Javascript
jQuery 函数实例分析【函数声明、函数表达式、匿名函数等】
May 19 jQuery
一篇超完整的Vue新手入门指导教程
Nov 18 Vue.js
vue3中provide && inject的使用
Jul 01 Vue.js
微信小程序页面滚动到指定位置代码实例
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打造属于自己的MVC框架
2012/03/07 PHP
如何使用php脚本给html中引用的js和css路径打上版本号
2015/11/18 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
2016/07/07 PHP
CL vs ForZe BO5 第三场 2.13
2021/03/10 DOTA
在Node.js中实现文件复制的方法和实例
2014/06/05 Javascript
高性能JavaScript模板引擎实现原理详解
2015/02/05 Javascript
详解javascript高级定时器
2015/12/31 Javascript
深入理解bootstrap框架之入门准备
2016/10/09 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
2016/12/13 Javascript
在vue项目中引用Iview的方法
2018/09/14 Javascript
vue引入axios同源跨域问题
2018/09/27 Javascript
vue中选项卡点击切换且能滑动切换功能的实现代码
2018/11/25 Javascript
微信小程序实现滑动切换自定义页码的方法分析
2018/12/29 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
[01:28]一分钟告诉你DOTA2 TI9不朽宝藏Ⅱ中有什么!
2019/07/09 DOTA
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
Python求两个文本文件以行为单位的交集、并集与差集的方法
2015/06/17 Python
python去掉空白行的多种实现代码
2018/03/19 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
python下的opencv画矩形和文字注释的实现方法
2019/07/09 Python
基于python实现蓝牙通信代码实例
2019/11/19 Python
python创建n行m列数组示例
2019/12/02 Python
用python进行视频剪辑
2020/11/02 Python
CSS3的一个简单导航栏实现
2015/08/03 HTML / CSS
HTML5 CSS3新的WEB标准和浏览器支持
2009/07/16 HTML / CSS
受希腊女神灵感的晚礼服、鸡尾酒礼服和婚纱:THEIA
2018/04/15 全球购物
土木工程建筑专业毕业生求职信
2013/10/21 职场文书
新闻学毕业生自荐信
2013/11/15 职场文书
初中数学教学反思
2014/01/16 职场文书
双十佳事迹材料
2014/01/29 职场文书
医学生临床实习自我评价
2014/03/07 职场文书
对公司合理化的建议书
2014/03/12 职场文书
2015年大学生暑期实习报告
2015/07/13 职场文书
2016同学毕业寄语大全
2015/12/04 职场文书
Java 数组内置函数toArray详解
2021/06/28 Java/Android
零基础学java之带返回值的方法的定义和调用
2022/04/10 Java/Android