写一个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还是有一席之地很多很多的小单位啊.其实还会用到 我也放一个例子吧虽然我也不是很肯定有没有人写的比我更好啊但是我相信 我这个还是蛮实用的 ...
随机推荐
- 100-continue
https://wiki.open.qq.com/wiki/技术优化原则#1._.E7.A8.8B.E5.BA.8F.E8.AE.BE.E8.AE.A1.E6.97.B6.E9.9C.80.E8.A6 ...
- 前端性能测试工具 : dynaTrace Ajax (还没写完)
今天开始写这个工具, #什么是dynaTrace Ajax? 随着 jQuery.Dojo.YUI 等框架的兴起让构建 Web2.0 应用更加容易,但随之带来的定位等应用问题也越来越难,尤其是与性能相 ...
- centos下如何开放某个端口?
命令如下: firewall-cmd --permanent --add-port=/tcp (开放22端口) firewall-cmd --reload
- html表格导出Excel的实例
1. 拼成出完整的HMTL的Table代码片段后,转成二进制byte[]类型并存入数据库中,供下载时调出来使用. System.Text.StringBuilder sb = new StringBu ...
- org.slf4j:slf4j-api:添加日志管理
org.slf4j:slf4j-api:添加日志管理 转 https://blog.csdn.net/wolfking0608/article/details/77855624 一个好的程序, 完 ...
- postman内置脚本说明
1. 清除一个全局变量 Clear a global variable 对应脚本: postman.clearGlobalVariable("variable_key"); 参数: ...
- realsense 图片与点云数据采集
- 基于keras的triplet_loss
https://blog.csdn.net/yjy728/article/details/79570554 https://blog.csdn.net/yjy728/article/details/7 ...
- linux记录-docker配置mysql
docker部署mysql 1.拉取镜像 docker pull mysql 2.docker rm containerID 删除镜像iD 3.创建镜像 docker run --name=m ...
- Python初级 3 基本数学运算
一. 四大基本运算操作符 1 加+ print(3 + 2) 2 减- print(3 - 2) 3 乘:* print(3 * 2) 4 除/, // print(3 / 2) print(3 // ...