当前位置:首页 > VUE

vue实现index list

2026-03-10 13:17:26VUE

Vue 实现 Index List(索引列表)

基础实现思路

使用 Vue 的 v-for 指令结合计算属性对数据进行分组,通过监听滚动事件实现高亮索引联动。核心步骤包括数据分组、渲染列表、添加右侧索引栏及滚动交互。

数据分组处理

假设原始数据为城市列表,按首字母分组:

computed: {
  groupedData() {
    const groups = {};
    this.listData.forEach(item => {
      const firstChar = item.name.charAt(0).toUpperCase();
      if (!groups[firstChar]) {
        groups[firstChar] = [];
      }
      groups[firstChar].push(item);
    });
    return Object.entries(groups).sort((a, b) => a[0].localeCompare(b[0]));
  }
}

模板结构

<div class="index-list">
  <!-- 主列表 -->
  <div class="list-container" ref="list" @scroll="handleScroll">
    <div v-for="([letter, items], index) in groupedData" :key="letter" :data-letter="letter">
      <h3 class="list-header">{{ letter }}</h3>
      <div class="list-item" v-for="item in items" :key="item.id">
        {{ item.name }}
      </div>
    </div>
  </div>

  <!-- 右侧索引栏 -->
  <div class="index-bar">
    <div 
      v-for="([letter]) in groupedData" 
      :key="letter"
      @click="scrollTo(letter)"
      :class="{ active: activeIndex === letter }"
    >
      {{ letter }}
    </div>
  </div>
</div>

滚动联动实现

methods: {
  scrollTo(letter) {
    const target = this.$refs.list.querySelector(`[data-letter="${letter}"]`);
    if (target) {
      this.$refs.list.scrollTo({
        top: target.offsetTop,
        behavior: 'smooth'
      });
    }
  },

  handleScroll() {
    const letters = this.groupedData.map(([letter]) => letter);
    const scrollTop = this.$refs.list.scrollTop;
    const listItems = this.$refs.list.querySelectorAll('[data-letter]');

    for (let i = 0; i < listItems.length; i++) {
      const item = listItems[i];
      const nextItem = listItems[i + 1];
      if (
        scrollTop >= item.offsetTop - 10 &&
        (!nextItem || scrollTop < nextItem.offsetTop - 10)
      ) {
        this.activeIndex = item.dataset.letter;
        break;
      }
    }
  }
}

样式优化建议

.index-list {
  display: flex;
  height: 100vh;
}

.list-container {
  flex: 1;
  overflow-y: auto;
}

.list-header {
  padding: 10px;
  background: #f5f5f5;
  position: sticky;
  top: 0;
}

.index-bar {
  width: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 12px;
}

.index-bar div {
  padding: 2px 0;
  cursor: pointer;
}

.index-bar div.active {
  color: #42b983;
  font-weight: bold;
}

性能优化方案

对于大数据量场景,可采用虚拟滚动技术。推荐使用第三方库如 vue-virtual-scroller

import { RecycleScroller } from 'vue-virtual-scroller';

// 模板中替换列表部分
<RecycleScroller
  class="scroller"
  :items="flattenedData"
  :item-size="50"
  key-field="id"
  v-slot="{ item }"
>
  <div v-if="item.isHeader" class="list-header">
    {{ item.letter }}
  </div>
  <div v-else class="list-item">
    {{ item.name }}
  </div>
</RecycleScroller>

完整组件封装建议

可将索引列表封装为可复用组件,通过 props 接收数据源:

vue实现index list

props: {
  data: {
    type: Array,
    required: true,
    validator: value => value.every(item => 'name' in item)
  },
  keyField: {
    type: String,
    default: 'id'
  }
}

标签: vueindex
分享给朋友:

相关文章

vue实现帖子

vue实现帖子

Vue 实现帖子功能 使用 Vue 实现帖子功能需要结合前端框架和后端数据交互,以下是实现的关键步骤和代码示例。 帖子列表展示 创建帖子列表组件,使用 v-for 渲染帖子数据,通过 axios 获…

vue 实现过滤

vue 实现过滤

Vue 实现过滤的方法 在 Vue 中实现过滤功能可以通过多种方式完成,包括使用计算属性、自定义过滤器、第三方库等。以下是几种常见的实现方法: 使用计算属性进行过滤 计算属性是 Vue 中最常用的过…

vue实现看板

vue实现看板

Vue 实现看板功能 使用 Vue 实现看板功能可以通过组件化开发、状态管理和拖拽库结合完成。以下是一个完整的实现方案: 基础项目结构 src/ ├── components/ │ ├── Ka…

vue实现swipe

vue实现swipe

Vue实现Swipe功能的方法 使用第三方库(推荐) Vue生态中有多个成熟的轮播/滑动组件库,例如vue-awesome-swiper或swiper/vue。以下是基于swiper/vue的实现示例…

vue实现左右菜单联动实现

vue实现左右菜单联动实现

Vue 实现左右菜单联动 使用事件总线通信 在 Vue 中可以通过事件总线实现左右菜单的通信。创建一个中央事件总线实例,让左右菜单通过事件监听和触发实现联动。 // eventBus.js impo…

vue实现拨号功能

vue实现拨号功能

Vue实现拨号功能的方法 使用HTML5的tel协议 在Vue模板中直接使用<a>标签的tel:协议实现拨号功能。这种方法适用于移动端浏览器,点击后会调起系统的拨号界面。 <tem…