今回は、Vue + better-scroll を使用してモバイル アルファベット順のインデックス ナビゲーションを実装する方法を説明します。Vue + better-scroll を使用してモバイル アルファベット順のインデックス ナビゲーションを実装するための 注意事項は何ですか。見てください。
デモ: リストビュー。表示するには Chrome モバイル モードを使用します。携帯モードに切り替えた後、スライドできない場合は更新すればOKです。 Github: モバイルアルファベットインデックスナビゲーションレンダリング設定環境
vue-cliとbetter-scrollを使用するため、最初にvue-cliをインストールしてからnpmでインストールする必要がありますbetter-scroll 。 better-scroll の簡単な紹介:better-scroll は、モバイル側でのさまざまなスクロール シナリオのニーズを解決することに焦点を当てたプラグインです (PC はすでにサポートされています)。そのコアは iscroll の実装に基づいており、その API 設計は基本的に iscroll と互換性があり、いくつかの機能が拡張され、いくつかのこれら 2 つに加えて、scss と vue-lazyload も使用されます。 scss プリプロセッサは誰もが知っていますが、他のものでも同様です。 Lazyload は遅延ロードを実装しますが、これなしでも使用できます。主な目的はエクスペリエンスを最適化することです。 データはNetEase Cloudの歌手リストを直接使用します。面倒な場合は、データに直接入力してください。 CSS スタイルは投稿しません。ソース コードを見てください。パフォーマンスの最適化が行われています。 better-scroll はネイティブ JS に基づいて実装されており、フレームワークには依存しません。コンパイルされたコード サイズは 63 kb、圧縮後は 35 kb、gzip 後はわずか 9 kb で、非常に軽量な JS ライブラリです。
基本スタイルの実装
v-forと両面ネスティングを直接使用して、右側の歌手リストとインデックス列を実装します。 HTML構造:<ul> <li v-for="group in singers" class="list-group" :key="group.id" ref="listGroup"> <h2 class="list-group-title">{{ group.title }}</h2> <ul> <li v-for="item in group.items" class="list-group-item" :key="item.id"> <img v-lazy="item.avatar" class="avatar"> <span class="name">{{ item.name }}</span> </li> </ul> </li> </ul> <p class="list-shortcut"> <ul> <li v-for="(item, index) in shortcutList" class="item" :data-index="index" :key="item.id" > {{ item }} </li> </ul> </p>
shortcutList () { return this.singers.map((group) => { return group.title.substr(0, 1) }) }
better-scroll を使用してください
スクロールを実現するには、better-scroll を使用してください。ちなみに、使用する際はインポートを忘れずに。created () { // 初始化 better-scroll 必须要等 dom 加载完毕 setTimeout(() => { this._initSrcoll() }, 20) }, methods: { _initSrcoll () { console.log('didi') this.scroll = new BScroll(this.$refs.listView, { // 获取 scroll 事件,用来监听。 probeType: 3 }) } }
クリックイベントを追加し、インデックスに移動イベントを追加してジャンプを実現します
まず、タッチスタートイベントをインデックスにバインドする必要があります(画面上で指が押されたときにトリガーされます)。v-onを直接使用するだけです。次に、インデックス値を取得できるようにインデックスにデータインデックスを追加する必要があります。 :data-index="index" を使用します。<p class="list-shortcut"> <ul> <li v-for="(item, index) in shortcutList" class="item" :data-index="index" :key="item.id" @touchstart="onShortcutStart" @touchmove.stop.prevent="onShortcutMove" > {{ item }} </li> </ul> </p>
created () { // 添加一个 touch 用于记录移动的属性 this.touch = {} // 初始化 better-scroll 必须要等 dom 加载完毕 setTimeout(() => { this._initSrcoll() }, 20) }, methods: { _initSrcoll () { this.scroll = new BScroll(this.$refs.listView, { probeType: 3, click: true }) }, onShortcutStart (e) { // 获取到绑定的 index let index = e.target.getAttribute('data-index') // 使用 better-scroll 的 scrollToElement 方法实现跳转 this.scroll.scrollToElement(this.$refs.listGroup[index]) // 记录一下点击时候的 Y坐标 和 index let firstTouch = e.touches[0].pageY this.touch.y1 = firstTouch this.touch.anchorIndex = index }, onShortcutMove (e) { // 再记录一下移动时候的 Y坐标,然后计算出移动了几个索引 let touchMove = e.touches[0].pageY this.touch.y2 = touchMove // 这里的 16.7 是索引元素的高度 let delta = Math.floor((this.touch.y2 - this.touch.y1) / 18) // 计算最后的位置 // * 1 是因为 this.touch.anchorIndex 是字符串,用 * 1 偷懒的转化一下 let index = this.touch.anchorIndex * 1 + delta this.scroll.scrollToElement(this.$refs.listGroup[index]) } }
モバイルコンテンツのインデックスの強調表示
うーん、現時点では少し複雑です。しかし、忍耐力があれば理解できるでしょう。 コンテンツがスクロールされたときに Y 軸のオフセット値を返すためには、better-scroll の on メソッドが必要です。したがって、better-scroll を初期化するときにコードを追加する必要があります。ちなみに、データにscrollYを追加し、currentIndex(ハイライトされたインデックスの位置を記録するために使用)をリッスンする必要があるため、データに追加することを忘れないでください。
_initSrcoll () { this.scroll = new BScroll(this.$refs.listView, { probeType: 3, click: true }) // 监听Y轴偏移的值 this.scroll.on('scroll', (pos) => { this.scrollY = pos.y }) }
_calculateHeight () { this.listHeight = [] const list = this.$refs.listGroup let height = 0 this.listHeight.push(height) for (let i = 0; i < list.length; i++) { let item = list[i] height += item.clientHeight this.listHeight.push(height) } } // [0, 760, 1380, 1720, 2340, 2680, 2880, 3220, 3420, 3620, 3960, 4090, 4920, 5190, 5320, 5590, 5790, 5990, 6470, 7090, 7500, 7910, 8110, 8870] // 得到这样的值
然后在 watch 中监听 scrollY,看代码:
watch: { scrollY (newVal) { // 向下滑动的时候 newVal 是一个负数,所以当 newVal > 0 时,currentIndex 直接为 0 if (newVal > 0) { this.currentIndex = 0 return } // 计算 currentIndex 的值 for (let i = 0; i < this.listHeight.length - 1; i++) { let height1 = this.listHeight[i] let height2 = this.listHeight[i + 1] if (-newVal >= height1 && -newVal < height2) { this.currentIndex = i return } } // 当超 -newVal > 最后一个高度的时候 // 因为 this.listHeight 有头尾,所以需要 - 2 this.currentIndex = this.listHeight.length - 2 } }
得到 currentIndex 的之后,在 html 中使用。
给索引绑定 class --> :class="{'current': currentIndex === index}"
最后再处理一下滑动索引的时候改变 currentIndex。
因为代码可以重复利用,且需要处理边界情况,所以就把
this.scroll.scrollToElement(this.$refs.listGroup[index])
重新写了个函数,来减少代码量。
// 在 scrollToElement 的时候,改变 scrollY,因为有 watch 所以就会计算出 currentIndex scrollToElement (index) { // 处理边界情况 // 因为 index 通过滑动距离计算出来的 // 所以向上滑超过索引框框的时候就会 < 0,向上就会超过最大值 if (index < 0) { return } else if (index > this.listHeight.length - 2) { index = this.listHeight.length - 2 } // listHeight 是正的, 所以加个 - this.scrollY = -this.listHeight[index] this.scroll.scrollToElement(this.$refs.listGroup[index]) }
lazyload
lazyload 插件也顺便说一下哈,增加一下用户体验。
使用方法
先 npm 安装
在 main.js 中 import,然后 Vue.use
import VueLazyload from 'vue-lazyload' Vue.use(VueLazyload, { loading: require('./common/image/default.jpg') })
添加一张 loading 图片,使用 webpack 的 require 获取图片。
然后在需要使用的时候,把 :src="" 换成 v-lazy="" 就实现了图片懒加载的功能。
总结
移动端字母索引导航就这么实现啦,感觉还是很有难度的哈(对我来说)。
主要就是使用了 better-scroll 的 on 获取移动偏移值(实现高亮)、scrollToElement 跳转到相应的位置(实现跳转)。以及使用 touch 事件监听触摸,来获取开始的位置,以及滑动距离(计算最后的位置)。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がVue + better-scroll を使用してモバイルのアルファベット順インデックス ナビゲーションを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。