vue.js2.0 實現(xiàn)better-scroll的滾動效果實例詳解
什么是 better-scroll
better-scroll 是一個移動端滾動的解決方案,它是基于 iscroll 的重寫,它和 iscroll 的主要區(qū)別在這里 。better-scroll 也很強大,不僅可以做普通的滾動列表,還可以做輪播圖、picker 等等。
<template>
<div>
<div class="goods">
<div class="menu-wrapper" ref="menuWrapper">
</div>
<div class="food-wrapper" ref="foodWrapper">
</div>
</div>
</div>
</template>
與1.0版本不同的是,我們使用的是ref
<script type="text/ecmascript-6">
import BScroll from "better-scroll";
export default {
data(){
return {
currentIndex:1,
goods:[]
}
},
created(){
this.classMap=['decrease','discount','special','invoice','guarantee'];
this.$http.get('/api/goods').then((response)=>{
response=response.body;
if (response.errno===ERR_OK) {
this.goods=response.data;
}
//dom結(jié)構(gòu)加載結(jié)束(nextTick這個接口是計算dom相關(guān)的,要確保原生dom已經(jīng)渲染了)
this.$nextTick(()=>{
this._initScroll();
});
});
},
methods:{
_initScroll(){
// 使用better-scroll實現(xiàn)的關(guān)鍵代碼
this.menuScroll=new BScroll(this.$refs.menuWrapper,{click:true});
this.foodScroll=new BScroll(this.$refs.foodWrapper,{click:true});
}
}
};
</script>
很簡單這樣頁面就可以滾動了,如下圖

但是,這樣左右兩個頁面并沒有聯(lián)動起來,需要我們再定義一個方法來計算滾動的高度,以及在計算屬性中計算左側(cè)當(dāng)前索引在哪里
從而定義左側(cè)邊欄的位置
computed:{
//用來計算左側(cè)當(dāng)前索引在哪,從而定位到左側(cè)邊欄的位置
currentIndex(){
for (let i = 0; i < this.listHeight.length; i++) {
var height1=this.listHeight[i] ;
var height2=this.listHeight[i+1];
if(!height2||(this.scrollY >= height1 && this.scrollY < height2)){
return i;
}
}
return 0;
}
},
methods:{
_initScroll(){
// 使用better-scroll實現(xiàn)的關(guān)鍵代碼
this.menuScroll=new BScroll(this.$refs.menuWrapper,{click:true});
this.foodScroll=new BScroll(this.$refs.foodWrapper,{
click: true,
//探針作用,實時監(jiān)測滾動位置
probeType: 3
});
this.foodScroll.on('scroll',(pos)=>{
this.scrollY=Math.abs(Math.round(pos.y))
});
},
_calculateHeight(){
let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
let height=0;
this.listHeight.push(height);
for (var i = 0; i < foodList.length; i++) {
let item=foodList[i];
height+=item.clientHeight;
this.listHeight.push(height);
}
}
}
//dom結(jié)構(gòu)加載結(jié)束(nextTick這個接口是計算dom相關(guān)的,要確保原生dom已經(jīng)渲染了)
this.$nextTick(()=>{
this._initScroll();
this._calculateHeight();
});
在dom渲染后,也是需要計算高度的.
滑動右邊,實現(xiàn)左邊聯(lián)動已經(jīng)實現(xiàn)了,接下來就是,點擊左邊的菜單,右邊的食物相應(yīng)滾動到具體的位置
給左邊菜單綁定一個事件:@click="selectMenu(index,$event)"
/左邊的菜單項的點擊事件
selectMenu(index,event){
//自己默認派發(fā)事件時(BScroll),_constructed默認為true.但原生的瀏覽器并沒有這個屬性
if (!event._constructed) {
return;
}
//運用BScroll滾動到相應(yīng)位置
//運用index去找到對應(yīng)的右側(cè)位置
let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
//滾動到相應(yīng)的位置
let el=foodList[index];
//設(shè)置滾動時間
this.foodScroll.scrollToElement(el,2000);
}
至此,整個聯(lián)動實現(xiàn)的,完整代碼如下
<template>
<div>
<div class="goods">
<div class="menu-wrapper" ref="menuWrapper">
<ul>
<li v-for="(item,index) in goods" class="menu-item" :class="{'current':currentIndex===index}" @click="selectMenu(index,$event)">
<span class="text border-1px">
<span v-show="item.type>0" class="icon" :class="classMap[item.type]"></span>{{item.name}}
</span>
</li>
</ul>
</div>
<div class="food-wrapper" ref="foodWrapper">
<ul>
<li v-for="(item,index) in goods" class="food-list food-list-hook">
<h1 class="title">{{item.name}}</h1>
<ul>
<li v-for="food in item.foods" class="food-item border-1px">
<div class="icon">
<img :src="food.icon" width="57" height="57" alt="">
</div>
<div class="content">
<h2 class="name">{{food.name}}</h2>
<p class="desc">{{food.description}}</p>
<div class="extra">
<span class="count">月售{{food.sellCount}}份</span>
<span>好評率{{food.rating}}%</span>
</div>
<div class="price">
<span class="now">¥{{food.price}}</span><span class="old" v-show="food.oldPrice">¥{{food.oldPrice}}</span>
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import BScroll from "better-scroll";
const ERR_OK=0;
export default {
props:{
seller:{
type:Object
}
},
data(){
return {
goods:[],
listHeight:[],
scrollY:0
}
},
created(){
this.classMap=['decrease','discount','special','invoice','guarantee'];
this.$http.get('/api/goods').then((response)=>{
response=response.body;
if (response.errno===ERR_OK) {
this.goods=response.data;
}
//dom結(jié)構(gòu)加載結(jié)束(nextTick這個接口是計算dom相關(guān)的,要確保原生dom已經(jīng)渲染了)
this.$nextTick(()=>{
this._initScroll();
this._calculateHeight();
});
});
},
computed:{
//用來計算左側(cè)當(dāng)前索引在哪,從而定位到左側(cè)邊欄的位置
currentIndex(){
for (let i = 0; i < this.listHeight.length; i++) {
var height1=this.listHeight[i] ;
var height2=this.listHeight[i+1];
if(!height2||(this.scrollY >= height1 && this.scrollY < height2)){
return i;
}
}
return 0;
}
},
methods:{
_initScroll(){
// 使用better-scroll實現(xiàn)的關(guān)鍵代碼
this.menuScroll=new BScroll(this.$refs.menuWrapper,{click:true});
this.foodScroll=new BScroll(this.$refs.foodWrapper,{
click: true,
//探針作用,實時監(jiān)測滾動位置
probeType: 3
});
this.foodScroll.on('scroll',(pos)=>{
this.scrollY=Math.abs(Math.round(pos.y))
});
},
_calculateHeight(){
let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
let height=0;
this.listHeight.push(height);
for (var i = 0; i < foodList.length; i++) {
let item=foodList[i];
height+=item.clientHeight;
this.listHeight.push(height);
}
},
//左邊的菜單項的點擊事件
selectMenu(index,event){
//自己默認派發(fā)事件時(BScroll),_constructed默認為true.但原生的瀏覽器并沒有這個屬性
if (!event._constructed) {
return;
}
//運用BScroll滾動到相應(yīng)位置
//運用index去找到對應(yīng)的右側(cè)位置
let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
//滾動到相應(yīng)的位置
let el=foodList[index];
//設(shè)置滾動時間
this.foodScroll.scrollToElement(el,2000);
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixin.styl";
.goods
display:flex
position:absolute
top:174px
bottom:46px
width:100%
overflow:hidden
.menu-wrapper
flex:0 0 80px
width: 80px
background:#f3f5f7
.menu-item
display:table
height:54px
width:56px
padding:0 12px
line-height:14px
&.current
position:relative
z-index:10
margin-top:-1px
background:#fff
font-weight:700
.text
border-none()
.icon
display:inline-block
vertical-align:top
margin-right:2px
width:12px
height:12px
background-size:12px 12px
background-repeat:no-repeat
&.decrease
bg-image('decrease_3')
&.discount
bg-image('discount_3')
&.guarantee
bg-image('guarantee_3')
&.invoice
bg-image('invoice_3')
&.special
bg-image('special_3')
.text
display:table-cell
vertical-align:middle
width:56px
border-1px(rgba(7,17,27,0.1))
font-size:12px
.food-wrapper
flex:1
.title
padding-left:14px
font-size:12px
color:rgb(147,153,159)
height:26px
border-left:2px solid #d9dde1
line-height:26px
background:#f3f5f7
.food-item
display:flex
margin:18px
padding-bottom:18px
border-1px(rgba(7,17,27,0.1))
&:last-child
border-none()
margin-bottom:0
.icon
flex:0 0 57px
margin-right:10px
.content
flex:1
.name
margin:2px 0 8px 0
height:14px
line-height:14px
font-size:14px
color:rgb(7,17,27)
.desc,.extra
line-height:10px
font-size:10px
color:rgb(147,153,159)
.desc
margin-bottom:8px
line-height:12px
.extra
.count
margin-right:12px
.price
font-weight:700
line-height:24px
.now
margin-right:8px
font-size:14px
color:rgb(240,20,20)
.old
text-decoration:line-through
font-size:10px
color:rgb(147,153,159)
</style>
總結(jié)
以上所述是小編給大家介紹的vue.js2.0 實現(xiàn)better-scroll的滾動效果實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- 詳解 vue better-scroll滾動插件排坑
- vue滾動軸插件better-scroll使用詳解
- vue利用better-scroll實現(xiàn)輪播圖與頁面滾動詳解
- vue滾動插件better-scroll使用詳解
- vue使用 better-scroll的參數(shù)和方法詳解
- vue中使用better-scroll實現(xiàn)滑動效果及注意事項
- vue better-scroll插件使用詳解
- vue2.0 better-scroll 實現(xiàn)移動端滑動的示例代碼
- vue和better-scroll實現(xiàn)列表左右聯(lián)動效果詳解
- Vue中利用better-scroll組件實現(xiàn)橫向滾動功能
相關(guān)文章
Vue 3 + Element Plus樹形表格全選多選及子節(jié)點勾選的問題解決方
在本文中,我們解決了Vue 3和Element Plus樹形表格中的全選、多選、子節(jié)點勾選和父節(jié)點勾選等常見問題,通過逐步實現(xiàn)這些功能,您可以構(gòu)建功能強大且用戶友好的樹形表格組件,以滿足各種數(shù)據(jù)展示需求,對Vue 3 Element Plus樹形表格相關(guān)知識感興趣的朋友一起看看吧2023-12-12
nuxt 實現(xiàn)在其它js文件中使用store的方式
這篇文章主要介紹了nuxt 實現(xiàn)在其它js文件中使用store的方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
Vue單頁式應(yīng)用(Hash模式下)實現(xiàn)微信分享的實例
本篇文章介紹了Vue單頁式應(yīng)用(Hash模式下)實現(xiàn)微信分享的實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
vue3?使用provide?inject父子組件傳值失敗且子組件不響應(yīng)
這篇文章主要介紹了vue3使用provide?inject父子組件傳值傳不過去且傳遞后子組件不具備響應(yīng)性問題解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08

