Pinia 怎么处理虚拟滚动列表中当前可视区域的状态

星静姑娘_4868

星静姑娘_4868

2026-10-30

511人浏览

原创

Pinia 不处理虚拟滚动的可视区域计算,只管理需持久化或跨组件共享的状态。运行时状态(如 scrollTop)应在组件内用 ref 管理;用户操作意图(如选中、展开)按 item ID 细粒度存入 Pinia;滚动位置可跨路由保存,但不可存储 visibleStartIndex 等渲染中间态。

pinia 怎么处理虚拟滚动列表中当前可视区域的状态

Pinia 本身不直接处理虚拟滚动中“当前可视区域”的状态,因为它不感知 DOM、滚动位置或渲染逻辑。它只负责状态的定义、存储与响应式同步。可视区域的计算、item 的动态切片、滚动监听这些事,属于组件层面的逻辑控制,Pinia 只在需要持久化或共享这部分状态时才介入。

关键要分清两层职责:

  • 虚拟滚动的运行时状态(如 scrollTop、visibleStartIndex、bufferSize)
    这些是瞬时 UI 衍生数据,通常用 ref 或 reactive 在组件内管理即可,无需上抛到 Pinia —— 毕竟每次滚动都触发 store 更新,既冗余又影响性能。

  • 需要跨组件保持或恢复的状态(如用户对某几条列表项的临时勾选、折叠/展开状态、编辑中的草稿行)
    这类“可视区域相关但语义明确”的状态,才适合交给 Pinia 管理,而且推荐按 item ID 做细粒度缓存。


✅ 场景一:记住用户对滚动中某几项的操作(如多选、展开)

  • 在 Pinia 中为该列表页定义专属 store,用对象映射存储每项的 UI 状态:

    // stores/listUI.ts
    export const useListUIStore = defineStore('listUI', () => {
      const itemStates = ref<record expanded: boolean selected:>>({})
    
      const setItemState = (id: string, partial: Partial<typeof itemstates.value>) => {
        itemStates.value[id] = { ...itemStates.value[id], ...partial }
      }
    
      const getItemState = (id: string) => itemStates.value[id] ?? { expanded: false, selected: false }
    
      return { itemStates, setItemState, getItemState }
    })</typeof></record>
  • 虚拟滚动组件中,在渲染每个 item 时读取并绑定:

    <virtualscroll :items="allItems" :item-size="64"><template item><listitem :item="item" :expanded="listUI.getItemState(item.id).expanded" :selected="listUI.getItemState(item.id).selected"> listUI.setItemState(item.id, { expanded: !listUI.getItemState(item.id).expanded })"
          @toggle-selected="() => listUI.setItemState(item.id, { selected: !listUI.getItemState(item.id).selected })"
        />
      </listitem></template></virtualscroll>

⚠️ 注意:不要把整个 visibleItems 数组存进 store,只存“用户意图”,比如 { '1001': { selected: true } } —— 轻量、可序列化、易清理。

Vuejs
Vuejs

Vue.js 官方推荐通过 npm 进行安装,这是构建现代化前端项目最主流的方式。在终端中执行 npm install vue 即可获取最新稳定版,如需指定版本可添加 @版本号,例如 npm install vue@3.4.0。安装前请确保已配置 Node.js 环境(推荐 v18 及以上版本),并建议将 npm 镜像源切换至国内镜像以提升下载速度。对于大型项目,还可通过 npm create v

下载

✅ 场景二:滚动位置需要跨路由保留(比如返回列表页时回到原位置)

  • 这类状态属于页面级“导航上下文”,适合存在页面专属 Pinia store 中:

    // stores/orderList.ts
    export const useOrderListStore = defineStore('orderList', () => {
      const scrollTop = ref(0)
      const lastSearchKeyword = ref('')
    
      // 页面激活时恢复
      function restoreScroll() {
        nextTick(() => {
          containerRef.value?.scrollTo({ top: scrollTop.value })
        })
      }
    
      return { scrollTop, lastSearchKeyword, restoreScroll }
    })
  • 在虚拟滚动容器的 onActivated 中调用 restoreScroll(),在 onDeactivated 中保存 containerRef.value?.scrollTop。


❌ 不推荐的做法

  • 把 visibleStartIndex / visibleEndIndex 存进 Pinia 并试图用它驱动渲染 —— 这破坏了虚拟滚动的响应式闭环,容易和 v-for 切片逻辑冲突。
  • 用 watch 监听 scrollTop 并频繁 commit 到 store —— 触发太密,无实际业务意义,纯属性能负担。
  • 所有列表页共用一个全局 store 存所有状态 —— 缺乏隔离,切换页面时状态互相污染。

Pinia 在虚拟滚动里的角色很清晰:它不替你算滚动,也不帮你复用 DOM,但它能稳稳托住那些“用户真正在意、且离开后还想回来”的状态。用得好,滚动体验丝滑;用错了,反而让简单逻辑变复杂。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

vue.js

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2723

5

前端如何实现即时通讯
前端如何实现即时通讯

实现即时通讯的方法有WebSocket、Long Polling、Server-Sent Events、WebRTC等等。详细介绍:1、WebSocket,它可以在客户端和服务器之间建立持久连接,实现实时的双向通信,前端可以使用 WebSocket API来创建WebSocket连接,并通过发送和接收消息来实现即时通讯;2、Long Polling,是一种模拟实时通信的技术等等。

2023.10.09

5923

6

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

6890

13

php和前端的关联介绍
php和前端的关联介绍

php既可以作为前端语言,也可以作为后端语言。想了解更多php和前端的相关内容,可以阅读本专题下面的文章。

2024.03.22

6638

10

前端外包工作内容有哪些
前端外包工作内容有哪些

前端外包工作内容包括:1. 网站和应用程序开发;2. 用户界面和交互设计;3. 用户体验优化;4. 设计和视觉开发;5. 跨浏览器兼容性;6. 性能优化;7. 维护和更新;8. 项目管理和沟通。想了解更多前端的相关内容,可以阅读本专题下面的文章。

2024.05.22

943

5

promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

2023.10.12

4640

6

html文本框类型介绍
html文本框类型介绍

html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

2023.10.12

4303

6

vue2.0和3.0区别
vue2.0和3.0区别

vue2.0和3.0区别:vue2的响应式原理是利⽤“Object.defineProperty()”对数据进⾏劫持结合发布订阅模式的⽅式来实现,vue3中使⽤了es6的proxy API对数据代理,实现对数据的监控。本专题为大家提供vue2.0和3.0区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.17

1714

5

vue3的生命周期有哪些
vue3的生命周期有哪些

vue3的生命周期:1、beforecreate;2、created;3、beforemount;4、mounted;5、beforeupdate;6、updated;7、beforedestroy;8、destroyed;9、activated;10、deactivated等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

12342

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue 教程
Vue 教程

共42课时 | 17.3万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.4万人学习

Vue.js 微实战--十天技能课堂
Vue.js 微实战--十天技能课堂

共18课时 | 1.7万人学习