vueではiscroll.jsを利用してpc端スクロール問題を解決します。


プロジェクトの中ではよくエリアオーバーの部分にスクロールバーが現れます。スクロールバーはpcの端でマウスローラーで上下を制御できます。移動端でマウスを使ってページをドラッグしてスクロールできます。この二つのシーンは全部ユーザーの習慣に合っています。しかし、このようなスクロールバーは普通は縦の「vertical」のスクロールバーです。もしpcの端に横スクロールバーが現れたら、「horizontal」です。処理をしない場合は、マウスで横スクロールバーのボタン「scroller bar」をドラッグしてスクロールエリアを表示することができます。また、綺麗にするために、普通のスクロールバーはスタイルを作成したり、隠したりします。横の領域はデフォルトではスクロールできません。
説明する
現在は、pc端のスクロール領域を移動端のように解決するために、マウスを使ってドラッグしてスクロール領域を直接スクロールすることができます。

pc端スクロール例図
スクロールの実例は以下のような知識点を使います。
  • は、vue-cli 3+iscroll.jsの組み合わせの方式を採用する。
  • は、Vueカスタムコマンドを使用して、iscrollの実装とパラメータ構成を実現する。
  • は、横スクロール領域と縦スクロール領域との連動を実現する。
  • は、横スクロールバーの中央に表示され、scrollIntoViewを使用する方法の違いを実現する

  • 三、カスタム命令v-i-scroll
    1、新規コマンドファイル
    ここではvueカスタムコマンドを使ってiscrollのインスタンスを初期化し、vue-cli 3プロジェクトディレクトリの下で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           option、instance-->
     const option = binding.value && binding.value.option
     const func = binding.value && binding.value.instance
     //       
     const optionType = option ? [].toString.call(option) : undefined
     const funcType = func ? [].toString.call(func) : undefined
     //    google      
     el.addEventListener('touchmove', function (e) {
      e.preventDefault()
     })
     //       new IScroll(el, iscrollOptions) 
     if (optionType === '[object Object]') {
      iscrollOptions = option
     }
     if (funcType === '[object Function]') {
      callBack = func
     }
     //   vnode  iscroll    iscroll         ,  iscroll    
     //          const myScroll = new IScroll('#wrapper',option)      
     vnode.scroll = new IScroll(el, iscrollOptions)
     //           , iscroll      
     if (callBack) callBack(vnode.scroll)
     },
     componentUpdated: function (el, binding, vnode, oldVnode) {
     //  scroll     vnode ,      
     vnode.scroll = oldVnode.scroll
     //    settimeout  refresh       ,  refresh         
     setTimeout(() => {
      vnode.scroll.refresh()
     }, 0)
     },
     unbind: function (el, binding, vnode, oldVnode) {
     //        iscroll  
     vnode.scroll = oldVnode.scroll
     vnode.scroll.destroy()
     vnode.scroll = null
     }
     })
     }
    }
    module.exports = VIScroll
    ここにiscroll.js 5の公式文書の住所、iscroll npmの住所を添付します。関連する属性と方法は自分で調べます。
    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) {
      <!--    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-i scrollコマンドは、2つのフィールドパラメータに入ってきました。
    option:iscrollパラメータを配置します。この中はscrollX、scrollyの二つの属性に注意します。横方向または縦方向のスクロールを表します。
    instance:コールバック方法は、vIscroll.jsにおいてコールバック方法を実行し、このコンポーネント方法でgetIscroll()を介してiscrollの例を取得する。
    3、上下スクロールエリア連動
    上のコードはオープンシーンの問題を解決できます。今は上下エリアの連動を実現します。横スクロールバーのボタンをクリックすることによって、選択状態になります。そして縦スクロールバーの対応する項目がトップにジャンプします。

    連動例図
    3-1、連動実現方法
    ボタンをクリックする方法:
    
    tabEvent (item, currentIndex) {
     this.currentId = item.id
     this.currentIndex = currentIndex
     <!--            ,    ,    -->
     ...
     <!--        -->
     this.$emit("switchTab", this.currentId, this.currentIndex)
    },
    
    
    垂直スクロールエリアのコンポーネント【App.vue】コードの部分は以下の通りで、switch Tab()方法に対して詳細な注釈を行います。
    
    <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 },
      <!--...      -->
      { id: 16, value: '   16 ', num: 16 }
      ],
      defalutOption: {
      bounce: true,
      mouseWheel: true,
      click: true,
      scrollX: false,
      scrollY: true
      },
      myScroll: null
     }
     },
     methods: {
     switchTab (currentId, currentIndex) {
      <!--       ,    “3”     “   3 ”,            offsetTop -->
      const offsetTop = this.$refs.detailItem[currentIndex].offsetTop
      <!--                 ,     iscroll   maxScrollY-->
      const y = offsetTop >= Math.abs(this.myScroll.maxScrollY) ? this.myScroll.maxScrollY : -offsetTop
      <!--  iscroll             -->
      this.myScroll.scrollTo(0, y)
     },
     <!--    -->
     getIscroll (iscroll) {
      this.myScroll = iscroll
     }
     }
    }
    </script>
    <style scoped>
    <!--  -->
    ...
    </style>
    この中で使っているのは全部iscrollプラグインが持っている属性と方法でローリング境界の判断とローリングを行います。JavaScript方法よりずっと便利です。それに、iscrollをローリング容器として使っています。vIscroll.jsで関連ブラウザのデフォルトイベントを無効にしました。
    3-2、中央に表示する
    ここでJavaScriptにはscrollIntoView()の方法があります。公式文書はリンクしています。この方法は現在の要素をブラウザウィンドウの可視領域にスクロールさせます。重要な欠点は、横スクロールと縦スクロールが同時にこの方法を使うと、スクロールエリアが有効で、もう一つは転がりません。
    scrollIntoView()を使用して、以下のように構成されている。
    
    this.$refs.tabItem[this.currentIndex].scrollIntoView({
     behavior: "smooth",
     inline: "center",
     block: 'nearest'
    })
    ここでは横スクロール領域に左右のボタンのペアを追加して、切替機能を実現します。

    切替ボタンの例図
    ボタンイベントの切り換え方法は、前のボタン、次のボタンの下付きを変更することによって、呼び出される方法で、切替機能を実現し、イベント方法の論理は以下の通りである。
    
    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++
     }
     <!--        -->
     this.tabEvent(this.$refs.tabItem[this.currentIndex], this.currentIndex)
    },
    ボタンをクリックしたイベントに対して以下のように中央論理を追加します。

    中央演算図
    
    tabEvent (item, currentIndex) {
     this.currentId = item.id
     this.currentIndex = currentIndex
     //             ,    
     const scrollContainerHalfWidth = this.$refs.scrollContainer.offsetWidth / 2
     //     item     
     const tabItemHalfWidth = this.$refs.tabItem[currentIndex].offsetWidth / 2
     //     ,              
     const halfDistance = scrollContainerHalfWidth - tabItemHalfWidth
     //     item          
     const currentItemOffsetLeft = this.$refs.tabItem[currentIndex].offsetLeft
     // scroll        
     const x = halfDistance - currentItemOffsetLeft
     this.myScroll.scrollTo(x, 0)
     this.$emit("switchTab", this.currentId, this.currentIndex)
    },
    4、まとめ
    1、全体の実例はiscrollプラグインの関連属性によって実現されたスクロールであり、同時にJavaScript方法によるコードの混乱を避ける。
    2、カスタムコマンドの方式を利用して、伝統的な実用化iscrollによるコード冗長を効果的に回避し、簡潔にすることができる。
    3、この例のスクロールオプションはすべて文字列であり、画像が現れたら、iscroll.refresh()方法を合理的に使用し、正確な時期にスクロールエリアを再計算し、スクロール境界が制限されることを避ける。
    締め括りをつける
    以上述べたのは小编がみんなに绍介するvueの中でiscroll.jsを利用してpc端の転がり问题を解决して、みんなに対してある程度助けることを望みます!