欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue中利用iscroll.js解決pc端滾動(dòng)問題

 更新時(shí)間:2020年02月15日 14:33:10   作者:翎魂雨  
這篇文章主要介紹了vue中利用iscroll.js解決pc端滾動(dòng)問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

項(xiàng)目中經(jīng)常遇到區(qū)域超出部分會出現(xiàn)滾動(dòng)條,滾動(dòng)條在pc端可以通過鼠標(biāo)滾輪控制上下,在移動(dòng)端可以通過鼠標(biāo)拖動(dòng)頁面進(jìn)行滾動(dòng),這兩種場景都是符合用戶習(xí)慣,然而這種滾動(dòng)條一般都是豎【vertical】項(xiàng)滾動(dòng)條,如果pc端出現(xiàn)橫向滾動(dòng)條【horizontal】,在不做處理的情況下,你只能用鼠標(biāo)拖動(dòng)橫向滾動(dòng)條按鈕【scrollerbar】展示滾動(dòng)區(qū)域,而且為了美觀,一般滾動(dòng)條會進(jìn)行樣式編寫或者隱藏,那么橫向區(qū)域默認(rèn)情況下就沒法滾動(dòng)。

二、描述

現(xiàn)為了解決pc端滾動(dòng)區(qū)域能像移動(dòng)端一樣,能夠通過鼠標(biāo)拖動(dòng)滾動(dòng)區(qū)域直接進(jìn)行滾動(dòng),如圖所示

pc端滾動(dòng)示例圖

滾動(dòng)實(shí)例用到知識點(diǎn)如下:

  1. 采用vue-cli3+iscroll.js組合的方式;
  2. 使用 vue 自定義指令實(shí)現(xiàn) iscroll 實(shí)例化和參數(shù)配置;
  3. 實(shí)現(xiàn)橫向滾動(dòng)區(qū)域和豎向滾動(dòng)區(qū)域之間的聯(lián)動(dòng);
  4. 實(shí)現(xiàn)橫向滾動(dòng)條居中顯示和使用scrollIntoView()方法的差別

三、自定義指令 v-iscroll

1、新建指令文件

這里使用 vue 自定義指令初始化 iscroll 實(shí)例,在 vue-cli3 項(xiàng)目目錄下新建vIscroll.js,文件代碼如下:

const IScroll = require('iscroll')
const VIScroll = {
 install: function (Vue, options) {
 Vue.directive('iscroll', {
 inserted: function (el, binding, vnode) {
 let callBack
 let iscrollOptions = options
 <!--vue組件中綁定的兩個(gè)參數(shù) option、instance-->
 const option = binding.value && binding.value.option
 const func = binding.value && binding.value.instance
 // 判斷輸入?yún)?shù)
 const optionType = option ? [].toString.call(option) : undefined
 const funcType = func ? [].toString.call(func) : undefined
 // 兼容 google 瀏覽器拖動(dòng)
 el.addEventListener('touchmove', function (e) {
  e.preventDefault()
 })
 // 將參數(shù)配置到new IScroll(el, iscrollOptions)中
 if (optionType === '[object Object]') {
  iscrollOptions = option
 }
 if (funcType === '[object Function]') {
  callBack = func
 }
 // 使用vnode綁定iscroll是為了讓iscroll對象能夠夸狀態(tài)傳遞,避免iscroll重復(fù)建立
 // 這里面跟官方網(wǎng)站 const myScroll = new IScroll('#wrapper',option) 初始化一樣
 vnode.scroll = new IScroll(el, iscrollOptions)
 // 如果指令傳遞函數(shù)進(jìn)來,把iscroll實(shí)例傳遞出去
 if (callBack) callBack(vnode.scroll)
 },
 componentUpdated: function (el, binding, vnode, oldVnode) {
 // 將scroll綁定到新的vnode上,避免多次綁定
 vnode.scroll = oldVnode.scroll
 // 使用 settimeout 讓refresh跳到事件流結(jié)尾,保證refresh時(shí)數(shù)據(jù)已經(jīng)更新完畢
 setTimeout(() => {
  vnode.scroll.refresh()
 }, 0)
 },
 unbind: function (el, binding, vnode, oldVnode) {
 // 解除綁定時(shí)要把iscroll銷毀
 vnode.scroll = oldVnode.scroll
 vnode.scroll.destroy()
 vnode.scroll = null
 }
 })
 }
}
module.exports = VIScroll

這里附上 iscroll.js 5 官方文檔地址, iscroll npm 包地址,相關(guān)屬性和方法自行查看。

2、加載引用指令

首先在 main.js 中加載指令:

import Vue from 'vue'
import App from './App.vue'
import "./assets/reset.css"
// 加載scroll指令
import VIscroll from './directive/vIscroll'
Vue.use(VIscroll)
Vue.config.productionTip = false

new Vue({
 render: h => h(App),
}).$mount('#app')

使用指令,摘自 tabList.vue 組件部分代碼如下:

<template>
 <div class="tab-container">
 <div
  class="scroll-container"
  v-iscroll="{
  option: iscrollConf,
  instance: getIscroll
  }"
  ref="scrollContainer"
 >
  <ul
  class="tab-li-container"
  ref="tabLiContainer"
  >
  <li
   class="tab-li-item"
   v-for="(item, index) in list"
   :key="item.id"
   :id="item.id"
   ref="tabItem"
   @click="tabEvent(item, index)"
  >
   <div
   class="item"
   :class="{
    'item-active': currentId == item.id
   }"
   >{{item.num}}</div>
  </li>
  </ul>
 </div>
 <div
  class="tab-left"
  @click="tabBtnEvent('left')"
 ><</div>
 <div
  class="tab-right"
  @click="tabBtnEvent('right')"
 >></div>
 </div>
</template>
<script>
export default {
 props: ['list'],
 data () {
 return {
  iscrollConf: {
  bounce: true,
  mouseWheel: true,
  click: true,
  scrollX: true,
  scrollY: false
  },
  currentId: null,
  currentIndex: 0,
  myScroll: null
 }
 },
 mounted () {
 this.$refs.tabLiContainer.style.width = this.$refs.tabItem[0].offsetWidth * this.list.length + 'px'
 this.$nextTick(() => {
  this.myScroll.refresh()
 })
 },
 methods: {
 tabEvent (item, currentIndex) {
  <!--點(diǎn)擊某個(gè)li 按鈕事件處理邏輯-->
 },
 tabBtnEvent (direction) {
  <!--左右切換邏輯事件-->
 },
 getIscroll (iscroll) {
  this.myScroll = iscroll
 }
 },
 watch: {
 list: {
  handler (l) {
  this.currentId = l[0].id
  },
  immediate: true,
  deep: true
 }
 }
}
</script>
<style scoped>
// 樣式
</style>

上述代碼中 v-iscroll 指令傳入兩個(gè)字段參數(shù):

option:配置iscroll參數(shù),這里面注意scrollX,scrollY兩個(gè)屬性,代表的是橫向還是豎向滾動(dòng);
instance:回調(diào)方法的調(diào)用, vIscroll.js 中執(zhí)行回調(diào)方法,通過該組件方法 getIscroll() 獲取到 iscroll 的實(shí)例。

3、上下滾動(dòng)區(qū)域聯(lián)動(dòng)

上面的代碼可以解決開篇場景中的問題,現(xiàn)在實(shí)現(xiàn)上下區(qū)域聯(lián)動(dòng),通過點(diǎn)擊橫向滾動(dòng)條某個(gè)按鈕,使其變成選中狀態(tài),然后豎向滾動(dòng)條對應(yīng)的項(xiàng)跳到首位,如圖所以:

聯(lián)動(dòng)示例圖

3-1、聯(lián)動(dòng)實(shí)現(xiàn)方法

點(diǎn)擊按鈕的方法:

tabEvent (item, currentIndex) {
 this.currentId = item.id
 this.currentIndex = currentIndex
 <!--這里實(shí)現(xiàn)按鈕始終居中顯示,暫時(shí)省略,下面補(bǔ)充-->
 ...
 <!--傳給豎向滾動(dòng)組件-->
 this.$emit("switchTab", this.currentId, this.currentIndex)
},

豎向滾動(dòng)區(qū)域組件【App.vue】代碼部分如下,并對 switchTab() 方法進(jìn)行詳細(xì)注釋:

<template>
 <div id="app">
 <TabList
  :list="list"
  @switchTab="switchTab"
 ></TabList>
 <!-- v-iscroll="defalutOption" -->
 <div
  v-iscroll="{
  option: defalutOption,
  instance: getIscroll
  }"
  class="tab-content-container"
  ref="detailItemContainer"
 >
  <ul class="tab-list-container">
  <li
   v-for="item in list"
   :key="item.id"
   class="list-item"
   ref="detailItem"
  >
   <div>{{item.value}}</div>
  </li>
  </ul>
 </div>
 </div>
</template>

<script>
import TabList from './components/tabList.vue'

export default {
 name: 'App',
 components: {
 TabList,
 },
 data () {
 return {
  list: [
  { id: 1, value: '這是第1題', num: 1 },
  <!--...省略數(shù)據(jù)展示-->
  { id: 16, value: '這是第16題', num: 16 }
  ],
  defalutOption: {
  bounce: true,
  mouseWheel: true,
  click: true,
  scrollX: false,
  scrollY: true
  },
  myScroll: null
 }
 },
 methods: {
 switchTab (currentId, currentIndex) {
  <!--對選中的當(dāng)前項(xiàng),這里就是“3”按鈕對應(yīng)的“這是第3題”,求出它距離父元素的上邊距offsetTop值-->
  const offsetTop = this.$refs.detailItem[currentIndex].offsetTop
  <!--滾動(dòng)的范圍不能超過這個(gè)滾動(dòng)體的底部,這里面用到iscroll的屬性maxScrollY-->
  const y = offsetTop >= Math.abs(this.myScroll.maxScrollY) ? this.myScroll.maxScrollY : -offsetTop
  <!--調(diào)用iscroll的方法進(jìn)行滾動(dòng)到相應(yīng)的位置-->
  this.myScroll.scrollTo(0, y)
 },
 <!--獲取實(shí)例-->
 getIscroll (iscroll) {
  this.myScroll = iscroll
 }
 }
}
</script>
<style scoped>
<!--樣式-->
...
</style>


這里面用到的都是 iscroll 插件自帶的屬性和方法進(jìn)行滾動(dòng)邊界的判斷和滾動(dòng),比用 JavaScript 方法方便的多,而且用了iscroll作為滾動(dòng)容器,已經(jīng)在vIscroll.js禁用了相關(guān)瀏覽器默認(rèn)事件。

3-2、居中顯示

這里 JavaScript 有個(gè) scrollIntoView() 方法, 官方文檔鏈接 ,這個(gè)方法讓當(dāng)前的元素滾動(dòng)到瀏覽器窗口的可視區(qū)域內(nèi)。關(guān)鍵缺點(diǎn)是,如果橫向滾動(dòng)和豎向滾動(dòng)都同時(shí)用到這個(gè)方法,只能保證一個(gè)滾動(dòng)區(qū)域有效,另一個(gè)會不滾動(dòng)。

使用 scrollIntoView() 方法配置如下:

this.$refs.tabItem[this.currentIndex].scrollIntoView({
 behavior: "smooth",
 inline: "center",
 block: 'nearest'
})

這里在橫向滾動(dòng)區(qū)域添加了一對左右按鈕,實(shí)現(xiàn)切換功能,如圖所示:

切換按鈕示例圖

切換按鈕事件方法就是通過改變上一個(gè)、下一個(gè)按鈕下標(biāo),調(diào)用方法,實(shí)現(xiàn)切換功能,切換事件方法邏輯如下:

tabBtnEvent (direction) {
 const max = this.$refs.tabItem.length
 if (direction === 'left' && this.currentIndex > 0) {
 this.currentIndex--
 }
 if (direction === 'right' && this.currentIndex < max - 1) {
 this.currentIndex++
 }
 <!--調(diào)用單擊按鈕事件-->
 this.tabEvent(this.$refs.tabItem[this.currentIndex], this.currentIndex)
},

下面對 單擊按鈕事件 添加居中邏輯,詳細(xì)代碼和解析圖如下,可以對比查看:

居中計(jì)算圖

tabEvent (item, currentIndex) {
 this.currentId = item.id
 this.currentIndex = currentIndex
 // 獲取滾動(dòng)容器的長度的一半,即中間點(diǎn)
 const scrollContainerHalfWidth = this.$refs.scrollContainer.offsetWidth / 2
 // 獲取單個(gè)item的一半長度
 const tabItemHalfWidth = this.$refs.tabItem[currentIndex].offsetWidth / 2
 // 求取插值,就是開始到中間開始位置的距離
 const halfDistance = scrollContainerHalfWidth - tabItemHalfWidth
 // 求取當(dāng)前item的相對總長度的偏移量
 const currentItemOffsetLeft = this.$refs.tabItem[currentIndex].offsetLeft
 // scroll 移動(dòng)到中間的值
 const x = halfDistance - currentItemOffsetLeft
 this.myScroll.scrollTo(x, 0)
 this.$emit("switchTab", this.currentId, this.currentIndex)
},

4、總結(jié)

1、整個(gè)實(shí)例用的都是iscroll插件相關(guān)屬性實(shí)現(xiàn)的滾動(dòng),避免同時(shí)使用JavaScript方法造成的代碼混亂;

2、利用自定義指令的方式有效的避免了傳統(tǒng)實(shí)例化iscroll帶來的代碼冗余,使其方便簡潔;

3、本實(shí)例滾動(dòng)選項(xiàng)都是字符串,如果出現(xiàn)圖片的情況,合理使用iscroll.refresh() 方法,在正確的時(shí)期重新計(jì)算滾動(dòng)區(qū)域,避免滾動(dòng)邊界受限;

總結(jié)

以上所述是小編給大家介紹的vue中利用iscroll.js解決pc端滾動(dòng)問題,希望對大家有所幫助!

相關(guān)文章

  • vue 指定組件緩存實(shí)例詳解

    vue 指定組件緩存實(shí)例詳解

    keep-alive 是 Vue 內(nèi)置的一個(gè)組件,可以使被包含的組件保留狀態(tài),或避免重新渲染。這篇文章主要介紹了vue 指定組件緩存,需要的朋友可以參考下
    2018-04-04
  • vue cli3中eslint報(bào)錯(cuò)no-undef和eslint規(guī)則配置方式

    vue cli3中eslint報(bào)錯(cuò)no-undef和eslint規(guī)則配置方式

    這篇文章主要介紹了vue cli3中eslint報(bào)錯(cuò)no-undef和eslint規(guī)則配置方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • vue3?hook重構(gòu)DataV的全屏容器組件詳解

    vue3?hook重構(gòu)DataV的全屏容器組件詳解

    這篇文章主要為大家介紹了vue3?hook重構(gòu)DataV的全屏容器組件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Vue?中使用?WebWorker的示例代碼

    Vue?中使用?WebWorker的示例代碼

    這篇文章主要介紹了Vue中使用WebWorker的示例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • vue文件上傳Required request part ‘file‘ is not present問題

    vue文件上傳Required request part ‘file‘ is&n

    這篇文章主要介紹了vue文件上傳Required request part ‘file‘ is not present問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 關(guān)于Ant-Design-Vue快速上手指南+排坑

    關(guān)于Ant-Design-Vue快速上手指南+排坑

    這篇文章主要介紹了關(guān)于Ant-Design-Vue快速上手指南+排坑,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Vue配合iView實(shí)現(xiàn)省市二級聯(lián)動(dòng)的示例代碼

    Vue配合iView實(shí)現(xiàn)省市二級聯(lián)動(dòng)的示例代碼

    本篇文章主要介紹了Vue配合iView實(shí)現(xiàn)省市二級聯(lián)動(dòng)的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • vue 獲取到數(shù)據(jù)但卻渲染不到頁面上的解決方法

    vue 獲取到數(shù)據(jù)但卻渲染不到頁面上的解決方法

    這篇文章主要介紹了vue 獲取到數(shù)據(jù)但卻渲染不到頁面上的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • vue實(shí)力踩坑?當(dāng)前頁push當(dāng)前頁無效的解決

    vue實(shí)力踩坑?當(dāng)前頁push當(dāng)前頁無效的解決

    這篇文章主要介紹了vue實(shí)力踩坑?當(dāng)前頁push當(dāng)前頁無效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue動(dòng)態(tài)添加表單的實(shí)現(xiàn)方法

    Vue動(dòng)態(tài)添加表單的實(shí)現(xiàn)方法

    在Vue.js應(yīng)用中,動(dòng)態(tài)表單是一個(gè)常見的需求,尤其是當(dāng)表單字段的數(shù)量和類型需要根據(jù)用戶輸入或系統(tǒng)狀態(tài)動(dòng)態(tài)變化時(shí),本文將詳細(xì)介紹如何在Vue中實(shí)現(xiàn)動(dòng)態(tài)表單的創(chuàng)建,并通過多個(gè)示例展示具體的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2024-09-09

最新評論