Using Vue3 VirtualScroller In Ionic Vue App
Tags: ionic, vue, webdev, tutorial
Published: 2021-04-10 21:30:02

Using [Vue3VirtualScroller](https://www.npmjs.com/package/vue3-virtual-scroller) In [Ionic Vue App](https://ionicframework.com/docs/vue/overview).

Ionic has a solution, but not one specifically for VueJS. If you look up the component in the [documentation]
(https://ionicframework.com/docs/api/virtual-scroll)

>ion-virtual-scroll is not supported in Vue. We plan on integrating with existing community-driven solutions for virtual scroll in the near future. Follow our [GitHub issue thread](https://github.com/ionic-team/ionic-framework/issues/17887) for the latest updates.

{% youtube 9hAtvG1QYII %}

## Getting Started
I started with the base list template generated from the ionic cli.
```
ionic start --template list --type vue
```
Next install the npm  package [vue3-virtual-scroller](https://www.npmjs.com/package/vue3-virtual-scroller)
```
npm install --save vue3-virtual-scroller
```
I was getting some module errors so I needed to modify the `shims-vue.d.ts` file to include the following.
```javascript
declare module '*.vue' {
  import { defineComponent } from 'vue'
  const component: ReturnType<typeof defineComponent>
  export default component
}

// THIS IS NEW
declare module 'vue3-virtual-scroller';
```
Modified `main.ts` with the following imports
```javascript
import VueVirtualScroller from 'vue3-virtual-scroller'
import 'vue3-virtual-scroller/dist/vue3-virtual-scroller.css'
```
And finally added the package with the following change
```javascript
const app = createApp(App)
  .use(IonicVue)
  .use(router)
  .use(VueVirtualScroller)
```

## In The Application
First i needed to create some fake data so I modified `messages.ts` to generate 255 records; I also added an image to the list so we could see what impact that had on the rendering
```javascript
const messages: Message[] = [...Array(255).keys()].map((x) => {
  return {
    id: x + 1,
    fromName: "Moe Chamont-" + x,
    subject: "Family Calendar - Version " + x,
    date: "Last Week",
    image: 'https://via.placeholder.com/150'
  };
});
```
I needed to modify the component that renders the list item to also include the image. All of the changes were made in the template of `MessageListItem.vue`
```html
<template>
  <ion-item
    v-if="message"
    :routerLink="'/message/' + message.id"
    :detail="false"
    class="list-item"
  >
    <!-- NEW CODE -->
    <div slot="start" style="margin:12px">
      <ion-img :src="message.image" style="width:80px;height:80px"></ion-img>
    </div>
    <ion-label class="ion-text-wrap">
      <h2>
        {{ message.fromName }}
        <span class="date">
          <ion-note>{{ message.date }}</ion-note>
          <ion-icon
            :icon="chevronForward"
            size="small"
            v-if="isIos()"
          ></ion-icon>
        </span>
      </h2>
      <h3>{{ message.subject }}</h3>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
    </ion-label>
  </ion-item>
</template>
```
Finally to the list; in this example i am using the fixed height version of the component. There are ways to handle variable height list item, see the package documentation.

Changes made to `Home.vue`
```html
<ion-content :fullscreen="true">
  <ion-list>
    <RecycleScroller
      class="scroller"
      :items="messages"
      :item-size="120"
      key-field="id"
      v-slot="{ item }"
    >
      <MessageListItem
        :key="item.id"
        :message="item"
      />
    </RecycleScroller>
  </ion-list>
</ion-content>
```

## Conclusion
See the source code here on codesandbox.io
- https://codesandbox.io/s/b8hrl

I read that someone stated they had issues on ios device, with the code that I have implemented above, there were no visible issues. If you have a more complex list implementation it is possible you might run into issues.

See additional video content on [Ionic Framework](https://ionicframework.com/), vuejs and reactjs on my @YouTube Channel
- https://buff.ly/300Zrus