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

Vue+better-scroll 實(shí)現(xiàn)通訊錄字母索引的示例代碼

 更新時(shí)間:2022年06月08日 10:45:37   作者:一只方方  
通訊錄字母索引是常用的一種功能,本文主要介紹了Vue+better-scroll 實(shí)現(xiàn)通訊錄字母索引,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

如??圖,實(shí)現(xiàn)一個(gè)滾動(dòng)內(nèi)容區(qū)域,右側(cè)字母滾動(dòng)索引定位;選擇和拖動(dòng)字母索引,對(duì)應(yīng)內(nèi)容滾動(dòng)到視窗

環(huán)境準(zhǔn)備:

  • 安裝better-scroll npm包
  • 安裝 mouseWheel 擴(kuò)展 BetterScroll 鼠標(biāo)滾輪的能力,開(kāi)啟鼠標(biāo)滾動(dòng)(移動(dòng)端非必須)
npm install @better-scroll/core  @better-scroll/mouse-wheel --save 

實(shí)現(xiàn)步驟:

數(shù)據(jù)結(jié)構(gòu)

  • 內(nèi)容區(qū)和索引按下圖數(shù)據(jù)結(jié)構(gòu)處理
export default {
  data() {
    return {
      entityList: [
        {
          key: 'A',
          list: ['氨基酸代謝病', '廣泛性發(fā)育障礙']
        },
        {
          key: 'B',
          list: ['巴特綜合征', '包涵體性結(jié)膜炎', '膀胱外翻', '鼻腔結(jié)外型NK/T細(xì)胞淋巴瘤']
        },
        {
          key: 'C',
          list: ['C5功能不全綜合征', '腸道蛔蟲(chóng)癥', '喘息樣支氣管炎']
        },
        {
          key: 'D',
          list: ['低氯性氮質(zhì)血癥綜合征', '石棉狀糠疹', 'Dravet綜合征']
        }
      ]
    };
  }
};

基本HTML

<!-- 內(nèi)容區(qū)域 -->
<!-- 最外層父容器wrapper,固定高度并且overflow:hidden-->
<div class="h-534px flex-1 wrapper overflow-hidden" ref="wrapper">
    <!-- content 注意滾動(dòng)區(qū)域一定是父容器的第一個(gè)子元素,當(dāng)高度超出父容器即可滾動(dòng) -->
    <ul class="content">
        <!-- v-for 循環(huán)出列表 -->
        <li
            v-for="(item, index) in entityList"
            :key="index"
            class="flex flex-col"
            ref="listGroup"
        >
            <div
                class="h-42px leading-42px text-sm font-bold pl-15px w-244px"
            >
                {{ item.key }}
            </div>
            <div class="flex flex-col">
                <span
                    class="h-42px leading-42px text-sm pl-15px g-clamp1 w-244px"
                    v-for="(it, i) in item.list"
                    :key="i"
                >
                    {{ it }}
                </span>
            </div>
        </li>
    </ul>
</div>
<!-- 索引 -->
<ul class="entityList w-15px bg-white">
     <!-- v-for 循環(huán)出索引 -->
    <li
        v-for="(item, index) in entityList"
        :key="index"
        :data-index="index"
        class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
    >
        {{ item.key }}
    </li>
</ul>

使用better-scroll實(shí)現(xiàn)內(nèi)容區(qū)列表的滾動(dòng)

<script>
//import 引入BScroll 
import BScroll from '@better-scroll/core';
import MouseWheel from '@better-scroll/mouse-wheel';
BScroll.use(MouseWheel);
export default {
    mounted() {
      //dom渲染完畢,初始化better-scroll
        this.$nextTick(() => {
            this.initBanner();
        });
    },
    methods: {
        initBanner() {
            if (this.scroll && this.scroll.destroy){
                this.scroll.refresh();//當(dāng) DOM 結(jié)構(gòu)發(fā)生變化的時(shí)候需重新計(jì)算 BetterScroll
                this.scroll.destroy();//銷(xiāo)毀 BetterScroll,解綁事件
            }
            this.scroll = new BScroll('.wrapper', {
                scrollY: true,//縱向滾動(dòng)
                click: true,
                mouseWheel: true,
                disableMouse: false, //啟用鼠標(biāo)拖動(dòng)
                disableTouch: false, //啟用手指觸摸
                probeType: 3 //設(shè)置為3,BetterScroll實(shí)時(shí)派發(fā) scroll 事件
            });
        }
    }
};
</script>

??注意:這里我們?cè)趍ounted時(shí)期,在this.$nextTick 的回調(diào)函數(shù)中初始化 better-scroll 。這時(shí)wrapper 的 DOM 已經(jīng)渲染了,我們可以正確計(jì)算它以及它內(nèi)層 content 的高度,以確保滾動(dòng)正常。

給索引添加點(diǎn)擊事件和移動(dòng)事件實(shí)現(xiàn)跳轉(zhuǎn)

<ul class="entityList w-15px bg-white">
  <li
      v-for="(item, index) in entityList"
      :key="index"
      :data-index="index"
      class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
      @touchstart="onShortcutStart" //點(diǎn)擊事件
      @touchmove.stop.prevent="onShortcutMove" //移動(dòng)事件
      >
    {{ item.key }}
  </li>
</ul>
created() {
  // 添加一個(gè) touch 用于記錄移動(dòng)的屬性
  this.touch = {};
  
  this.$nextTick(() => {
      this.initBanner();
  });
},
methods: {
  onShortcutStart(e) {
      // 獲取到綁定的 index
      let index = e.target.getAttribute('data-index');
      // 使用 better-scroll 的 scrollToElement 方法實(shí)現(xiàn)跳轉(zhuǎn)
      this.scroll.scrollToElement(this.$refs.listGroup[index]);
      // 記錄一下點(diǎn)擊時(shí)候的 Y坐標(biāo) 和 index
      let firstTouch = e.touches[0].pageY;
      this.touch.y1 = firstTouch;
      this.touch.anchorIndex = index;
  },
  onShortcutMove(e) {
      // 再記錄一下移動(dòng)時(shí)候的 Y坐標(biāo),然后計(jì)算出移動(dòng)了幾個(gè)索引
      let touchMove = e.touches[0].pageY;
      this.touch.y2 = touchMove;
      // 這里的 16.7 是索引元素的高度
      let delta = Math.floor((this.touch.y2 - this.touch.y1) / 18);

      // 計(jì)算最后的位置
      let index = this.touch.anchorIndex * 1 + delta;
      this.scroll.scrollToElement(this.$refs.listGroup[index]);
  }
}

給索引添加高亮

  • 在data中定義currentIndex用于索引高亮的判斷,并在html中綁定class
data() {
  return {
    currentIndex: 0,
    entityList: [
        {
          key: 'A',
          list: ['氨基酸代謝病', '廣泛性發(fā)育障礙']
        }]
    }
}
<ul class="entityList w-15px bg-white">
    <li
        v-for="(item, index) in entityList"
        :key="index"
        :data-index="index"
        class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
        @touchstart="onShortcutStart"
        @touchmove.stop.prevent="onShortcutMove"
        :class="{ current: currentIndex === index }"
    >
        {{ item.key }}
    </li>
</ul>

接下來(lái)求currentIndex:

  • 先通過(guò)better-scroll 的on(type, fn, context)方法,監(jiān)聽(tīng)當(dāng)前實(shí)例上的scroll,得到內(nèi)容區(qū)y軸的偏移量
initBanner() {
    if (this.scroll && this.scroll.destroy) {
        this.scroll.refresh();
        this.scroll.destroy();
    }
    this.scroll = new BScroll('.wrapper', {
        scrollY: true,
        click: true,
        mouseWheel: true,
        disableMouse: false, //啟用鼠標(biāo)拖動(dòng)
        disableTouch: false, //啟用手指觸摸
        probeType: 3
    });
  // 監(jiān)聽(tīng)Y軸偏移的值
    this.scroll.on('scroll', pos => {
        this.scrollY = pos.y;
    });
},
  • data中初始化 listHeight ,添加calculateHeight() 方法計(jì)算內(nèi)容區(qū)高度
data() {
    return {
        listHeight: [],
        currentIndex: 0,
        entityList: [
            {
              key: 'A',
              list: ['氨基酸代謝病', '廣泛性發(fā)育障礙']
            }
        ]
    }
}
//計(jì)算內(nèi)容區(qū)高度
_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);
    }
}
  • data中初始化scrollY為-1,在 watch 中監(jiān)聽(tīng) scrollY
data() {
  return {
    scrollY: -1
    currentIndex: 0,
    listHeight: [],
      entityList: [
        {
          key: 'A',
          list: ['氨基酸代謝病', '廣泛性發(fā)育障礙']
        }
      ]
  }
}
 watch: {
    scrollY(newVal) {
        // 向下滑動(dòng)的時(shí)候 newVal 是一個(gè)負(fù)數(shù),所以當(dāng) newVal > 0 時(shí),currentIndex 直接為 0
        if (newVal > 0) {
            this.currentIndex = 0;
            return;
        }
        // 計(jì)算內(nèi)容區(qū)高度判斷 對(duì)應(yīng)索引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;
            }
        }
        // 當(dāng)超 -newVal > 最后一個(gè)高度的時(shí)候
        // 因?yàn)?this.listHeight 有頭尾,所以需要 - 2
        this.currentIndex = this.listHeight.length - 2;
    }
}

這樣就得到了currentIndex 實(shí)現(xiàn)索引高亮的特效

全部代碼

<template>
    <div>
        <!-- 內(nèi)容區(qū)域 -->
        <div class="h-534px flex-1 wrapper overflow-hidden" ref="listview">
            <ul class="content">
                <li
                    v-for="(item, index) in entityList"
                    :key="index"
                    class="flex flex-col"
                    ref="listGroup"
                >
                    <div class="h-42px leading-42px text-sm font-bold pl-15px w-244px">
                        {{ item.key }}
                    </div>
                    <div class="flex flex-col">
                        <Link
                            class="h-42px leading-42px text-sm pl-15px g-clamp1 w-244px"
                            v-for="(it, i) in item.list"
                            :key="i"
                            :to="{
                                name: 'Yidian',
                                query: {
                                    title: it
                                }
                            }"
                        >
                            {{ it }}
                        </Link>
                    </div>
                </li>
            </ul>
        </div>
        <!-- 索引 -->
        <ul class="entityList w-15px bg-white">
            <li
                v-for="(item, index) in entityList"
                :key="index"
                :data-index="index"
                class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
                @touchstart="onShortcutStart"
                @touchmove.stop.prevent="onShortcutMove"
                :class="{ current: currentIndex === index }"
            >
                {{ item.key }}
            </li>
        </ul>
    </div>
</template>
<script>
import BScroll from '@better-scroll/core';
import MouseWheel from '@better-scroll/mouse-wheel';
BScroll.use(MouseWheel);
export default {
    data() {
        return {
            currentIndex: 0,
            listHeight: [],
            entityList: [
                {
                    key: 'A',
                    list: ['氨基酸代謝病', '廣泛性發(fā)育障礙']
                },
                {
                    key: 'B',
                    list: ['巴特綜合征', '包涵體性結(jié)膜炎', '膀胱外翻', '鼻腔結(jié)外型NK/T細(xì)胞淋巴瘤']
                },
                {
                    key: 'C',
                    list: ['C5功能不全綜合征', '腸道蛔蟲(chóng)癥', '喘息樣支氣管炎']
                },
                {
                    key: 'D',
                    list: ['低氯性氮質(zhì)血癥綜合征', '石棉狀糠疹', 'Dravet綜合征']
                },
                {
                    key: 'E',
                    list: ['耳聾', '兒童癲癇', '兒童頭痛', '兒童急性中耳炎']
                },
                {
                    key: 'F',
                    list: ['腹肌缺如綜合征', '肥大性神經(jīng)病', '肺缺如', '樊尚咽峽炎', '腹壁疝']
                }
            ],
            scrollY: -1
        };
    },
    mounted() {
        this.touch = {};
        this.$nextTick(() => {
            this.initBanner();
        });
    },
    methods: {
        //初始化scroll
        initBanner() {
            if (this.scroll && this.scroll.destroy) {
                this.scroll.refresh();
                this.scroll.destroy();
            }
            this.scroll = new BScroll('.wrapper', {
                scrollY: true,
                click: true,
                mouseWheel: true,
                disableMouse: false, //啟用鼠標(biāo)拖動(dòng)
                disableTouch: false, //啟用手指觸摸
                probeType: 3
            });
            this._calculateHeight();
            this.scroll.on('scroll', pos => {
                console.log(pos.y);
                this.scrollY = pos.y;
            });
        },
        onShortcutStart(e) {
            // 獲取到綁定的 index
            let index = e.target.getAttribute('data-index');
            // 使用 better-scroll 的 scrollToElement 方法實(shí)現(xiàn)跳轉(zhuǎn)
            this.scroll.scrollToElement(this.$refs.listGroup[index]);
            // 記錄一下點(diǎn)擊時(shí)候的 Y坐標(biāo) 和 index
            let firstTouch = e.touches[0].pageY;
            this.touch.y1 = firstTouch;
            this.touch.anchorIndex = index;
        },
        onShortcutMove(e) {
            // 再記錄一下移動(dòng)時(shí)候的 Y坐標(biāo),然后計(jì)算出移動(dòng)了幾個(gè)索引
            let touchMove = e.touches[0].pageY;
            this.touch.y2 = touchMove;

            // 這里的 16.7 是索引元素的高度
            let delta = Math.floor((this.touch.y2 - this.touch.y1) / 18);

            // 計(jì)算最后的位置
            let index = this.touch.anchorIndex * 1 + delta;
            //注意這里需要判斷邊界,不然拖動(dòng)到頂部和底部會(huì)報(bào)錯(cuò)
            if (index >= 0 && index <= this.entityList.length - 2) {
            this.scroll.scrollToElement(this.$refs.listGroup[index]);
            }
        },
        //計(jì)算索引內(nèi)容高度
        _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);
            }
        }
    },
    watch: {
        scrollY(newVal) {
            // 向下滑動(dòng)的時(shí)候 newVal 是一個(gè)負(fù)數(shù),所以當(dāng) newVal > 0 時(shí),currentIndex 直接為 0
            if (newVal > 0) {
                this.currentIndex = 0;
                return;
            }
            // 計(jì)算 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;
                }
            }
            // 當(dāng)超 -newVal > 最后一個(gè)高度的時(shí)候
            // 因?yàn)?this.listHeight 有頭尾,所以需要 - 2
            this.currentIndex = this.listHeight.length - 2;
        }
    }
};
</script>

<style scoped lang="postcss">
.tabActive {
    @apply font-bold;
}
.tabActive::after {
    content: '';
    display: block;
    width: 18px;
    height: 3px;
    background: #00c2b0;
    border-radius: 2px;
    position: absolute;
    bottom: 0;
}
.sortActive {
    color: #00c2b0;
}
.select-left {
    @apply w-110px;
}
.select-left-item {
    @apply pl-15px h-42px text-sm;
}
.entityList {
    position: fixed;
    right: 8px;
    top: 156px;
}
.current {
    border-radius: 50%;
    background: #00beb0;
    color: #fff;
}
.typeAct {
    @apply bg-white text-primary;
}
</style>

總結(jié)

  • 參考了很多網(wǎng)上的資料,相對(duì)于原生實(shí)現(xiàn),better-scroll帶來(lái)了更大的便利,但是同時(shí)也需要我們對(duì)better-scroll有一定的了解。

參考文獻(xiàn)

better-scroll官方文檔

參考博客

到此這篇關(guān)于Vue+better-scroll 實(shí)現(xiàn)通訊錄字母索引的文章就介紹到這了,更多相關(guān)Vue+better-scroll 實(shí)現(xiàn)通訊錄字母索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue數(shù)據(jù)代理的實(shí)現(xiàn)流程逐步講解

    Vue數(shù)據(jù)代理的實(shí)現(xiàn)流程逐步講解

    通過(guò)一個(gè)對(duì)象代理對(duì)另一個(gè)對(duì)象中的屬性的操作(讀/寫(xiě)),就是數(shù)據(jù)代理。要搞懂Vue數(shù)據(jù)代理這個(gè)概念,那我們就要從Object.defineProperty()入手,Object.defineProperty()是Vue中比較底層的一個(gè)方法,在數(shù)據(jù)劫持,數(shù)據(jù)代理以及計(jì)算屬性等地方都或多或少的用到了本函數(shù)
    2023-01-01
  • 詳解Vue項(xiàng)目引入CreateJS的方法(親測(cè)可用)

    詳解Vue項(xiàng)目引入CreateJS的方法(親測(cè)可用)

    CreateJS是基于HTML5開(kāi)發(fā)的一套模塊化的庫(kù)和工具。這篇文章主要介紹了Vue項(xiàng)目引入CreateJS的方法(親測(cè)),需要的朋友可以參考下
    2019-05-05
  • vue emit之Property or method “$$v“ is not defined的解決

    vue emit之Property or method “$$v“ i

    這篇文章主要介紹了vue emit之Property or method “$$v“ is not defined的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn)

    vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn)

    這篇文章主要介紹了vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue單頁(yè)面如何通過(guò)prerender-spa-plugin插件進(jìn)行SEO優(yōu)化

    vue單頁(yè)面如何通過(guò)prerender-spa-plugin插件進(jìn)行SEO優(yōu)化

    這篇文章主要介紹了vue單頁(yè)面如何通過(guò)prerender-spa-plugin插件進(jìn)行SEO優(yōu)化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 解決找不到模塊“xxx.vue”或其相應(yīng)的類(lèi)型聲明問(wèn)題

    解決找不到模塊“xxx.vue”或其相應(yīng)的類(lèi)型聲明問(wèn)題

    這篇文章主要介紹了解決找不到模塊“xxx.vue”或其相應(yīng)的類(lèi)型聲明問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2022-10-10
  • VUE的tab頁(yè)面切換的四種方法

    VUE的tab頁(yè)面切換的四種方法

    這篇文章主要介紹了VUE的tab頁(yè)面切換的四種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • vue使用exif獲取圖片經(jīng)緯度的示例代碼

    vue使用exif獲取圖片經(jīng)緯度的示例代碼

    這篇文章主要介紹了vue使用exif獲取圖片經(jīng)緯度的示例代碼,幫助大家更好的利用vue獲取圖片信息,感興趣的朋友可以了解下
    2020-12-12
  • 解決vue-router在同一個(gè)路由下切換,取不到變化的路由參數(shù)問(wèn)題

    解決vue-router在同一個(gè)路由下切換,取不到變化的路由參數(shù)問(wèn)題

    今天小編就為大家分享一篇解決vue-router在同一個(gè)路由下切換,取不到變化的路由參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • vue路由傳參方式的方式總結(jié)及獲取參數(shù)詳解

    vue路由傳參方式的方式總結(jié)及獲取參數(shù)詳解

    vue 路由傳參的使用場(chǎng)景一般都是應(yīng)用在父路由跳轉(zhuǎn)到子路由時(shí),攜帶參數(shù)跳轉(zhuǎn),下面這篇文章主要給大家介紹了關(guān)于vue路由傳參方式的方式總結(jié)及獲取參數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07

最新評(píng)論