vue使用better-scroll實現(xiàn)滑動以及左右聯(lián)動
本文實例為大家分享了vue實現(xiàn)滑動以及左右聯(lián)動效果的具體代碼,供大家參考,具體內(nèi)容如下
一、首先需要在項目中引入better-scroll
1. 在package.json 直接寫入 "better-scroll":"^1.15.1" 版本以github上為準(目前最新)
2.cpnm install 在node_modules 可以查看版本是否安裝
3.直接在你的組件里面寫入import BScroll from 'better-scroll';
二、better-scroll優(yōu)點
1.體驗像原生:滾動非常流暢,而且沒有滾動條。
2.滾動位置固定:在vue中通過路由切換頁面時組件會自動滾動到頂部,需要監(jiān)聽滾動行為才能讓滾動位置固定,better-scroll解決了這個問題。
三、下面是在項目中的使用
移動端很常見的效果,當滑動右邊部分的時候,左邊會聯(lián)動顯示與當前內(nèi)容相符合的標題高亮,當點擊左邊某一個標題的時候,右邊會自動滑動到相應的內(nèi)容。
項目如下圖:

實現(xiàn)及說明
1.滾動效果
better-scroll在使用的時候需要在dom元素渲染完成之后初始化better-scroll的實例,初始化的時候,先要獲取需要滑動的元素,然后在初始化的時候將獲取到的元素傳遞給初始化函數(shù),此時便可實現(xiàn)滑動效果
2.左右聯(lián)動效果
左右聯(lián)動效果的實現(xiàn),是better-scroll通過監(jiān)聽事件實現(xiàn)的。
首先獲取到右邊內(nèi)容盒子的高度,然后獲取到該盒子中每一項的高度并做前n項高度累加(第n項的高度是前n項的高度和)存儲到listHeight數(shù)組中。在初始化的時候傳遞屬性probeType=3 (探針的效果,時時獲取滾動高度),并給右邊的內(nèi)容盒子對象監(jiān)聽scroll事件,從而時時獲取Y軸位置,來與listHeight數(shù)組中的數(shù)據(jù)做比較,時時計算當前的索引值,并給對邊對應索引值的項添加背景色高亮,從而實現(xiàn)右邊滑動,聯(lián)動左邊。
當點擊左邊的每一項的時候,獲取到當前的索引值,并根據(jù)當前的索引值獲取到與右邊內(nèi)容盒子中對應索引的元素,右邊的盒子元素通過監(jiān)聽scrollToElement,并傳遞獲取到的對應索引元素和動畫時間,從而實現(xiàn)點擊左邊,實現(xiàn)右邊聯(lián)動;
實現(xiàn)代碼如下:
<template>
<section class="box">
<div class="head">
head
</div>
<div class="content">
<div class="left" ref="left">
<ul>
<li v-for="(item, index) in left" :key="item" :class="{current: currentIndex == index}" @click="selectItem(index, $event)">
<span class="left-item">{{item}}</span>
</li>
</ul>
</div>
<div class="right" ref="right">
<ul>
<li class="right-item right-item-hook" v-for="item in right" :key="item.name">
<h2>{{item.name}}</h2>
<ul>
<li v-for="num in item.content" :key="num.name">
<div>{{item.name+num}}</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</section>
</template>
<script>
import BScroll from 'better-scroll'
export default {
data () {
return {
left: ['a', 'b', 'c', 'd', 'e', 'f'],
right: [
{
name: 'a',
content: ['1', '2', '3', '4', '5']
},
{
name: 'b',
content: ['1', '2', '3', '4', '5']
},
{
name: 'c',
content: ['1', '2', '3', '4', '5']
},
{
name: 'd',
content: ['1', '2', '3', '4', '5']
},
{
name: 'e',
content: ['1', '2', '3', '4', '5']
},
{
name: 'f',
content: ['1', '2', '3', '4', '5']
},
],
listHeight: [],
scrollY: 0, //實時獲取當前y軸的高度
clickEvent: false
}
},
methods: {
_initScroll () {
//better-scroll的實現(xiàn)原理是監(jiān)聽了touchStart,touchend事件,所以阻止了默認的事件(preventDefault)
//所以在這里做點擊的話,需要在初始化的時候傳遞屬性click,派發(fā)一個點擊事件
//在pc網(wǎng)頁瀏覽模式下,點擊事件是不會阻止的,所以可能會出現(xiàn)2次事件,所以為了避免2次,可以在綁定事件的時候把$event傳遞過去
this.lefts = new BScroll(this.$refs.left, {
click: true
})
this.rights = new BScroll(this.$refs.right, {
probeType: 3 //探針的效果,實時獲取滾動高度
})
//rights這個對象監(jiān)聽事件,實時獲取位置pos.y
this.rights.on('scroll', (pos) => {
this.scrollY = Math.abs(Math.round(pos.y))
})
},
_getHeight () {
let rightItems = this.$refs.right.getElementsByClassName('right-item-hook')
let height = 0
this.listHeight.push(height)
for(let i = 0; i < rightItems.length; i++){
let item = rightItems[i]
height += item.clientHeight
this.listHeight.push(height)
}
},
selectItem(index,event){
this.clickEvent = true
//在better-scroll的派發(fā)事件的event和普通瀏覽器的點擊事件event有個屬性區(qū)別_constructed
//瀏覽器原生點擊事件沒有_constructed所以當時瀏覽器監(jiān)聽到該屬性的時候return掉
if(!event._constructed){
return
}else{
let rightItems = this.$refs.right.getElementsByClassName('right-item-hook')
let el = rightItems[index]
this.rights.scrollToElement(el, 300)
}
}
},
mounted () {
this.$nextTick(() => {
this._initScroll()
this._getHeight()
})
},
computed: {
currentIndex () {
for(let i = 0; i < this.listHeight.length; i ++){
let height = this.listHeight[i]
let height2 = this.listHeight[i + 1]
//當height2不存在的時候,或者落在height和height2之間的時候,直接返回當前索引
//>=height,是因為一開始this.scrollY=0,height=0
if(!height2 || (this.scrollY >= height && this.scrollY < height2)){
return i
}
if(this.listHeight[this.listHeight.length - 1] - this.$refs.right.clientHeight <= this.scrollY){
if(this.clickTrue){
return this.currentNum
}else{
return (this.listHeight.length - 1)
}
}
}
//如果this.listHeight沒有的話,就返回0
return 0
}
}
}
</script>
<style scoped>
.content{
display: flex;
position: absolute;
top:100px;
bottom:100px;
width:100%;
overflow: hidden;
background: #eee;
}
.left{
flex: 0 0 80px;
width:80px;
background-color: #f3f5f7;
}
.left li{
width: 100%;
height: 100%;
}
.current{
background-color: red;
}
.left-item{
display: block;
width:100%;
height:100px;
line-height: 50px;
text-align: center;
border-bottom:1px solid yellow;
}
.right{
flex: 1;
}
.right-item li{
width:100%;
height:100px;
line-height:100px;
text-align: center;
border-bottom: 1px solid yellow;
}
*{
list-style: none;
margin: 0;
padding: 0;
}
</style>
關于vue.js組件的教程,請大家點擊專題vue.js組件學習教程進行學習。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Vue聯(lián)動Echarts實現(xiàn)數(shù)據(jù)大屏展示
這篇文章主要為大家介紹了Vue聯(lián)動Echarts實現(xiàn)數(shù)據(jù)大屏的展示示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
優(yōu)雅的elementUI table單元格可編輯實現(xiàn)方法詳解
這篇文章主要介紹了優(yōu)雅的elementUI table單元格可編輯實現(xiàn)方法詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
Vue.js每天必學之計算屬性computed與$watch
Vue.js每天必學之計算屬性computed與$watch,為大家詳細講解計算屬性computed與$watch,感興趣的小伙伴們可以參考一下2016-09-09
Vue使用Element-UI實現(xiàn)分頁效果全過程
element-ui官網(wǎng)上有分頁實現(xiàn)的功能,簡單方便又好用,也有很多分頁的樣式,你可以根據(jù)需要去選擇自己想要的樣式,下面這篇文章主要給大家介紹了關于Vue使用Element-UI實現(xiàn)分頁效果的相關資料,需要的朋友可以參考下2023-04-04
vue之input輸入框防抖debounce函數(shù)的使用方式
這篇文章主要介紹了vue之input輸入框防抖debounce函數(shù)的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11

