Vue 展示长列表

617 阅读2分钟

解决方案 vue-virtual-scroller

一、vue2 使用 vue-virtual-scroller

1. 安装

安装 vue-virtual-scroller

npm i vue-virtual-scroller

安装完后 package.js 中会多出

"vue-virtual-scroller": "^1.0.10"
  1. vue 中引入 vue-virtual-scroller main.js 中引入 vue-virtual-scroller 并 use 它
// vue virtual scroller
import "vue-virtual-scroller/dist/vue-virtual-scroller.css" // 引入它的 css
import VueVirtualScroller from "vue-virtual-scroller" // 引入它
Vue.use(VueVirtualScroller) // use 它

vue-virtual-scroller 中包含这几个组件,具体都能做什么可以看官方文档,这里只介绍 RecycleScroller

  • RecycleScroller
  • DynamicScroller
  • DynamicScrollerItem

3. 使用

vue 的内容

<recycle-scroller
    class="virtual-list"
    :buffer="1000"
    :prerender="200"
    style="height: 400px"
    :item-height="100"
    :items="longList">
    <template v-slot="{ item, index }">
        <div class="list-item" :key="item.id">
            <p class="mr-2">{{ item.id }}</p>
            <p>{{ item.name }}</p>
        </div>
    </template>
</recycle-scroller>
data() {
    return {
        longList: []
    }
},
created() {
    for (let i = 0; i < 100000; i++) {
        this.longList.push({id: i, name: Math.random()})
    }
}

注意!!!!! : 这里需要特别注意, recycle-scroller 组件必须设置高度,自己计算也好,提前指定也好,必须设置,不然会出错。 recycle-scroller 的接收参数说明:官方文档

  1. 效果展示 测试:js 中在初始化的时候创建了 10万条数据,载入毫无延迟

  2. 关于元素的 :hover 比较保险的做法是:

由于展示的界面是经过处理的,如果想实现 :hover 效果,需要实现 class 内容
.vue-recycle-scroller__item-view.hover 或
.hover .some-element-inside-the-item-view

不过也可以像对待普通 dom 一样,直接使用 :hover 就可以了

二、vue3 使用 vue-virtual-scroller

vue3 中使用的组件跟 vue2 只有引入的时候不同,多了@next,其它都一样。

安装 npm i vue-virtual-scroller@next

npm i vue-virtual-scroller@next

安装完后 package.js 中会多出

"vue-virtual-scroller": "^2.0.0-alpha.1"

main.js

// vue virtual scroller
import "vue-virtual-scroller/dist/vue-virtual-scroller.css" // 引入它的 css
import VueVirtualScroller from "vue-virtual-scroller" // 引入它
app.use(VueVirtualScroller) // use 它

三、结语

所有的操作都在官方 API 文档中有:

github.com/Akryum/vue-…

查看在线例子

kylebing.cn/tools/wubi-…
kylebing.cn/e/#/demos/v…

四、补充:

Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化。但是有些时候我们的组件就是纯粹的数据展示,不会有任何改变,可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = Object.freeze(users);
  }
};