前言:在學習黃軼老師的《Vue.js高仿餓了麼外賣App》課程中接觸到了better-scroll第三方JavaScript組件庫,這是黃軼老師本身基於iscroll重寫的庫。這裏結合黃軼老師的知乎文章和Vue2.0項目對better-scroll的具體應用,只做爲學習,對其中的原理和應用步驟作一個梳理。javascript
移動端項目列表滾動的需求html
豎直滾動:vue
橫向滾動:java
什麼是better-scrollgit
better-scroll 是一個移動端滾動的解決方案,它是基於 iscroll 的重寫,它和 iscroll 的主要區別在這裏。better-scroll 也很強大,不只能夠作普通的滾動列表,還能夠作輪播圖、picker 等等。github
npm install better-scroll --save
better-scroll 的滾動原理npm
瀏覽器的滾動原理:瀏覽器
瀏覽器的滾動條你們都會遇到,當頁面內容的高度超過視口高度的時候,會出現縱向滾動條;當頁面內容的寬度超過視口寬度的時候,會出現橫向滾動條。也就是當咱們的視口展現不下內容的時候,會經過滾動條的方式讓用戶滾動屏幕看到剩餘的內容。bash
better-scroll的滾動原理:app
div class="wrapper">
<ul class="content">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
當 content 的高度不超過父容器的高度,是不能滾動的,而它一旦超過了父容器的高度,咱們就能夠滾動內容區了,這就是 better-scroll 的滾動原理
import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper, {})
關於參數:better-scroll 對外暴露了一個 BScroll 的類,咱們初始化只須要 new 一個類的實例便可。
第一個參數就是咱們 wrapper 的 DOM 對象,第二個是一些配置參數,具體參考 better-scroll 的文檔。
better-scroll 的初始化時機:
在《Vuejs高仿餓了麼外賣App》課程中是這樣處理的:
<template>
<div class="wrapper" ref="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
mounted() {
this.$nextTick(() => {
this.scroll = new Bscroll(this.$refs.wrapper, {})
})
}
}
</script>
this.$nextTick()
這個方法做用是當數據被修改後使用這個方法會回調獲取更新後的dom再render出來; 若是不在下面的this.$nextTick()
方法裏回調這個方法,數據改變後再來計算滾動軸就會出錯實現效果:
better-scroll不能滾動的緣由
須要DOM加載完成後才能正確應用. vue中應用在$nextTick中,異步初始化
子元素高度須要超過父元素。並且父元素須要設置高度(這纔是better-scroll可以滾動的原理)
better-scroll在使用的時候,滾動只做用於第一個子元素,其它的元素都會被忽略。在vue中,獲取的ref是ratings,它的子元素包含rating-content和rating-wrapper等多個同級元素,那麼須要在這些同級元素外層,ratings內層再套一個<div>,這個<div>纔是須要滾動的部分
<div class="ratings" ref="ratings">
<div> //這纔是滾動的範圍
<div class="rating-content"></div>
<div class="rating-wrapper"></div>
<v-split></v-split>
</div>
</div>
隱藏切換顯示都會致使插件參數的scrollerHeight:0。此時須要加上click:true,使better-scroll支持點擊事件,再調用下refresh()從新渲染DOM就好了
this.$nextTick(() => {
if(!this.scroll){
this.scroll = new BScroll(this.$refs.food, {
click: true
})
}else{
this.scroll.refresh();
}
})