当前位置:首页 > 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 实现选择分类的方法 使用 v-model 绑定选择值 在 Vue 中可以通过 v-model 指令实现双向数据绑定,适用于下拉选择框(<select>)。以下是一个基本示例: &…

vue 实现简单登陆

vue 实现简单登陆

以下是一个使用 Vue 3 实现的简单登录功能示例,包含表单验证和基础交互逻辑: 创建 Vue 组件 <template> <div class="login-containe…

vue实现发表

vue实现发表

Vue 实现发表功能 在 Vue 中实现发表功能通常涉及表单处理、数据绑定和网络请求。以下是实现步骤和代码示例: 表单设计与数据绑定 创建一个表单用于输入发表内容,使用 v-model 进行数据双向…

vue实现分屏

vue实现分屏

Vue 实现分屏的方法 分屏功能通常用于展示多个独立内容区域,以下是几种常见的实现方式: 使用 CSS Grid 布局 通过 CSS Grid 可以轻松创建分屏布局,在 Vue 组件中直接应用样式:…

vue实现级联

vue实现级联

Vue 实现级联选择器的方法 级联选择器(Cascader)是常见的表单组件,用于处理多层级联动数据选择(如省市区选择)。以下是几种实现方式: 基于 Element UI 的 el-cascader…

vue el 实现

vue el 实现

Vue 中使用 Element UI (el) 的实现方法 Element UI 是一个基于 Vue 的组件库,提供丰富的 UI 组件,常用于快速构建企业级中后台产品。以下介绍 Vue 项目中集成和使…