Page Vue Component

Page in Framework7 has the same meaning as when you think about web pages. Page is the main component to display and operate content.

Page Vue component represents Framework7's Page.

Page Components

There are following components included:

Page Properties

PropTypeDefaultDescription
<f7-page> properties
namestringPage name
messages-contentbooleanEnable if you use Messages component inside to add required extra styling
page-contentbooleantrueWhen enabled it automatically adds page-content element inside. Useful to disable when you need to use few page-content elements for tabs
tabsbooleanEnable if you use Page as Tabs wrapper
login-screenbooleanEnable if you use Login Screen inside of the page to add required extra styling
no-swipebackbooleanDisables swipeback feature for the current page (affects iOS theme only)
with-subnavbarbooleanEnable if you have Sub Navbar inside of the page
no-navbarbooleanEnable if you use common Navbar layout and need to hide common Navbar (or use another one) for this page (affects iOS theme only)
no-toolbarbooleanEnable if you use common Toolbar/Tabbar layout and need to hide Toolbar (or use another one) for this page
hide-bars-on-scrollbooleanHide Navbar & Toolbar on page scroll
hide-navbar-on-scrollbooleanHide Navbar on page scroll
hide-toolbar-on-scrollbooleanHide Toolbar on page scroll
ptrbooleanEnables Pull To Refresh
ptr-distancenumberCustom pull to refresh trigger distance. By default (if not specified) it is 44px.
ptr-preloaderbooleantrueDisable if you want to use custom pull to refresh preloader element
ptr-bottombooleanfalseEnables pull to refresh from bottom
ptr-mousewheelbooleanfalseEnables pull to refresh with mousewheel (for desktop apps). Works only for PTR top
infinitebooleanEnables Infinite Scroll
infinite-topbooleanEnables infinite scroll on top of the page
infinite-distancenumberDistance from the bottom of page (in px) to trigger infinite scroll event. By default (if not specified), it is 50 (px)
infinite-preloaderbooleantrueDisable if you want to use custom infinite-scroll preloader
<f7-page-content> properties
tabbooleanEnable if you use page-content as Tab
tab-activebooleanEnable if the current tab is active
ptr
ptr-distance
ptr-preloader
ptr-bottom
ptr-mousewheel
infinite
infinite-top
infinite-distance
infinite-preloader
hide-bars-on-scroll
hide-navbar-on-scroll
hide-toolbar-on-scroll
messages-content
login-screen
Same as <f7-page> properties

Page Events

EventDescription
<f7-page> events
page:mountedEvent will be triggered when page with keepAlive route is mounted/attached to DOM
page:initEvent will be triggered after Framework7 initialize required page's components and navbar
page:reinitThis event will be triggered in case of navigating to the page that was already initialized
page:beforeinEvent will be triggered when everything initialized and page is ready to be transitioned into view (into active/current position)
page:afterinEvent will be triggered after page transitioned into view
page:beforeoutEvent will be triggered right before page is going to be transitioned out of view
page:afteroutEvent will be triggered after page transitioned out of view
page:beforeunmountEvent will be triggered when page with keepAlive route is going to be unmounted/detached from DOM
page:beforeremoveEvent will be triggered right before Page will be removed from DOM. This event could be very useful if you need to detach some events / destroy some plugins to free memory. This event won't be triggered for keepAlive routes.
page:tabshowEvent will be triggered when page's parent View as Tab becomes visible
page:tabhideEvent will be triggered when page's parent View as Tab becomes hidden
ptr:pullstartEvent will be triggered when you start to move pull to refresh content
ptr:pullmoveEvent will be triggered during you move pull to refresh content
ptr:pullendEvent will be triggered when you release pull to refresh content
ptr:refreshEvent will be triggered when pull to refresh enters in "refreshing" state
ptr:doneEvent will be triggered after pull to refresh is done and it is back to initial state (after calling pullToRefreshDone method)
infiniteEvent will be triggered when page scroll reaches specified (in data-distance attribute) distance to the bottom.
<f7-page-content> events
tab:showEvent will be triggered when Tab becomes visible/active
tab:hideEvent will be triggered when Tab becomes hidden/inactive
ptr:pullstart
ptr:pullmove
ptr:pullend
ptr:refresh
ptr:done
infinite
Same as <f7-page> events

Page Slots

Page Vue component (<f7-page>) has additional slots for custom elements:

<f7-page>
  <div slot="fixed">Fixed element</div>
  <p>Page content goes here</p>
</f7-page>

<!-- Renders to: -->

<div class="page">
  <div>Fixed element</div>
  <div class="page-content">
    <p>Page content goes here</p>
  </div>
</div>

Examples

Infinite Scroll

infinite-scroll.vue
<template>
  <f7-page
    infinite
    :infinite-distance="50"
    :infinite-preloader="showPreloader"
    @infinite="loadMore"
  >
    <f7-navbar title="Infinite Scroll"></f7-navbar>
    <f7-block-title>Scroll bottom</f7-block-title>
    <f7-list strong-ios outline-ios dividers-ios>
      <f7-list-item
        v-for="(item, index) in items"
        :key="index"
        :title="`Item ${item}`"
      ></f7-list-item>
    </f7-list>
  </f7-page>
</template>
<script>
import { f7Navbar, f7Page, f7BlockTitle, f7List, f7ListItem } from 'framework7-vue';

export default {
  components: {
    f7Navbar,
    f7Page,
    f7BlockTitle,
    f7List,
    f7ListItem,
  },
  data() {
    return {
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
      allowInfinite: true,
      showPreloader: true,
    };
  },
  methods: {
    loadMore() {
      const self = this;
      if (!self.allowInfinite) return;
      self.allowInfinite = false;

      setTimeout(() => {
        if (self.items.length >= 200) {
          self.showPreloader = false;
          return;
        }

        const itemsLength = self.items.length;

        for (let i = 1; i <= 20; i += 1) {
          self.items.push(itemsLength + i);
        }

        self.allowInfinite = true;
      }, 1000);
    },
  },
};
</script>

Pull To Refresh

pull-to-refresh.vue
<template>
  <f7-page ptr :ptr-mousewheel="true" @ptr:refresh="loadMore">
    <f7-navbar title="Pull To Refresh"></f7-navbar>
    <f7-list media-list strong-ios dividers-ios outline-ios>
      <f7-list-item
        v-for="(item, index) in items"
        :key="index"
        :title="item.title"
        :subtitle="item.author"
      >
        <template #media>
          <img :src="item.cover" width="44" style="border-radius: 8px" />
        </template>
      </f7-list-item>

      <f7-block-footer>
        <p>
          Just pull page down to let the magic happen.<br />Note that pull-to-refresh feature is
          optimised for touch and native scrolling so it may not work on desktop browser.
        </p>
      </f7-block-footer>
    </f7-list>
  </f7-page>
</template>
<script>
import { f7Navbar, f7Page, f7List, f7ListItem, f7BlockFooter } from 'framework7-vue';

export default {
  components: {
    f7Navbar,
    f7Page,
    f7List,
    f7ListItem,
    f7BlockFooter,
  },
  data() {
    return {
      items: [
        {
          title: 'Yellow Submarine',
          author: 'Beatles',
          cover: 'https://cdn.framework7.io/placeholder/abstract-88x88-1.jpg',
        },
        {
          title: "Don't Stop Me Now",
          author: 'Queen',
          cover: 'https://cdn.framework7.io/placeholder/abstract-88x88-2.jpg',
        },
        {
          title: 'Billie Jean',
          author: 'Michael Jackson',
          cover: 'https://cdn.framework7.io/placeholder/abstract-88x88-3.jpg',
        },
      ],
      songs: ['Yellow Submarine', "Don't Stop Me Now", 'Billie Jean', 'Californication'],
      authors: ['Beatles', 'Queen', 'Michael Jackson', 'Red Hot Chili Peppers'],
    };
  },
  methods: {
    loadMore(done) {
      const self = this;

      setTimeout(() => {
        const picURL = `https://cdn.framework7.io/placeholder/abstract-88x88-${
          Math.floor(Math.random() * 10) + 1
        }.jpg`;
        const song = self.songs[Math.floor(Math.random() * self.songs.length)];
        const author = self.authors[Math.floor(Math.random() * self.authors.length)];

        self.items.push({
          title: song,
          author,
          cover: picURL,
        });

        done();
      }, 1000);
    },
  },
};
</script>