写一个vue的滚动条插件

组件源码如下: vue-scroll.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>
写一个vue的滚动条插件的更多相关文章
- 分享一个自己写的vue多语言插件smart-vue-i18n
前言 目前有比较成熟的方案(vue-i18n)了解了下,并且实用了一下感觉对于我在使用的项目来说略显臃肿,功能比较多,所以压缩的会比较大,在移动端不太适合所以自己花一天时间撸了一个vue多语言插件,压 ...
- 写一个vue组件
写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...
- 大前端工程化之写一个简单的webpack插件
今天写一个简单的webpack插件,来学习一下webpack插件 webpack插件机制可以使开发者在webpack构建过程中加入自己的行为,来针对自己项目中的一些需求做一些定制化 首先我们得知道一个 ...
- 写一个Vue loading 插件
什么是vue插件? 从功能上说,插件是为Vue添加全局功能的一种机制,比如给Vue添加一个全局组件,全局指令等: 从代码结构上说,插件就是一个必须拥有install方法的对象,这个方法的接收的第一个参 ...
- 如何优雅的写一个Vue 的弹框
写Vue或者是react 都会遇见弹框的问题.也尝试了多种办法来写弹框,一直都不太满意,今天特地看了一下 Element UI 的源码,模仿着写了一个简易版. 大概有一下几个问题: 1.弹框的层级问题 ...
- 使用 js,自己写一个简单的滚动条
当我们给元素加上 overflow: auto; 的时候,就会出现滚动条,然而浏览的不同,滚动条的样式大不一样,有些甚至非常丑. 于是就想着自己写一个滚动条,大概需要弄清楚一下这几个点: 1.滚动条 ...
- 面试题:你能写一个Vue的双向数据绑定吗?
在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...
- 学习如何写一个vue插件【入门篇】
#### 疑答 1.市面上已经有那么多插件可用,为什么还要造轮子?学习.借鉴思想.应用到开发 2.能否在项目中使用?与网上插件使用相同 更新维护问题怎么解决? 自身动力,使用者反馈等 #### 准 ...
- 写一个简单的JQ插件(例子)
虽然现在 vue angular react 当道啊但是那 JQ还是有一席之地很多很多的小单位啊.其实还会用到 我也放一个例子吧虽然我也不是很肯定有没有人写的比我更好啊但是我相信 我这个还是蛮实用的 ...
随机推荐
- 优化Unity游戏项目的脚本(下)
金秋9月,我们祝所有的老师们:教师节快乐 ! 今天,我们继续分享来自捷克的开发工程师Ondřej Kofroň,分享C#脚本的一系列优化方法. 在优化Unity游戏项目的脚本(上)中,我们介绍了如何查 ...
- Tosca :配置环境参数
# 跟Modules TestCases并列 ,右键创建 #再右键创建配置(结构自己安排) #再创建配置参数 #使用配置参数 #引用配置的环境参数
- could not find 'gopls
安装go tools 安装以上后用vim打开go代码,使用函数跳转时会出现: E718: Funcref requiredvim-go: could not find 'gopls'. Run :Go ...
- linux下phpmailer发送邮件出现SMTP ERROR: Failed to connect to server: (0)错误
转自:https://www.cnblogs.com/raincowl/p/8875647.html //Create a new PHPMailer instance $mail = new PHP ...
- Python之Pandas绘图,设置显示中文问题
# -*- coding: utf-8 -*- # author:baoshan import pandas as pd import matplotlib.pyplot as plt plt.rcP ...
- 网站无法连接上,但能上QQ的解决办法
一句话:修改DNS的IP地址 参考win10修改IP地址:https://jingyan.baidu.com/article/19192ad8eef0c9e53e570717.html 在网络上搜索合 ...
- Qt编写自定义控件65-光晕日历
一.前言 操作系统的更新迭代速度非常快,基本上三五年就有个新版本出来,WIN10操作系统还是一个比较成功的系统,据说现在市场份额越来越大,XP的份额已经很小,WIN7的份额也在逐步减少,在最新的WIN ...
- 定时显示提示信息(TToolTip)
{ 修改者:ghs 日期:20071218 功能:在原版本的基础上增加. RegisterControl:注册需要提示的控件. BeginHelp:设置光标状态为帮助crHelp: 鼠标弹起后,显示注 ...
- jquery img src赋值
不用Jquery时:document.getElementById("imageId").src = "xxxx.jpg"; 用Jquery时:$(" ...
- React:快速上手(8)——前后端分离的跨域访问与会话保持
React:快速上手(8)——前后端分离的跨域访问与会话保持 跨域访问 跨域是指从一个域名的网页去请求另一个域名的资源.比如从http://www.baidu.com/ 页面去请求http://www ...