'Is there a method within q-layout to scroll to top in quasar?

I have a q-layout (just a simple one as below) within a q-dialog where I need to scroll top of the page when a certain process is completed.

    <q-dialog v-model="is_form_dialog_open">
        <q-layout view="hhh LpR fff" container ref="scroll_area" id="top" style="max-height: 1200px: width: 1200px; max-width: 1200px;" class="bg-white shadow-3 rounded-borders">
            <q-header elevated class="bg-grey-3 text-black">
                <q-toolbar>
                    <q-toolbar-title> Add </q-toolbar-title>
                </q-toolbar>
            </q-header>
            <q-page-container class="row q-ma-sm">
                ...
            </q-page-container>
            <q-footer elevated class="bg-grey-2 text-white">
                <q-toolbar class="justify-end q-pa-sm q-gutter-sm">
                    <q-btn label="Test" @click="test()" color="primary" />  
                </q-toolbar>
            </q-footer>
        </q-layout>
    </q-dialog>

There is a component q-page-scroller easily scrolls to top of the layout but it uses a clicked. I need a way where I can trigger this (scroll to top) via method. Is there a method to scroll to the top of the q-layout?



Solution 1:[1]

yes there is a method:

...
methods: {
   GoToTop() {
       window.scrollTo(0, 0);
   },
...

coupled to a button :

<q-btn icon="open_in_browser" @click="GoToTop()" />

Solution 2:[2]

I use this code from here to scroll to top. Just call the method with your header element as el.

import { scroll } from 'quasar'
const { getScrollTarget, setScrollPosition } = scroll // takes an element 

object function scrollToElement (el) { 
       const target = getScrollTarget(el)
       const offset = el.offsetTop const duration = 1000 setScrollPosition(target, offset, duration) 
}

Solution 3:[3]

My two cents for OP's question.

  1. stores/ui.js Create Pinia store for shared UI states and methods.
import { defineStore } from 'pinia'

export const useUI = defineStore('ui-store', {
  actions: {
    setScrollPosition: (axis = 'vertical', offset = 0, duration = 0) => null,
  },
})
  1. layouts/MainLayout.vue Create your layout and wrap it with q-scroll-area component
<template>
  <q-layout>
    <q-scroll-area
      ref="scrollPageRef"
      style="height: 100vh">
      <q-page-container>
        <router-view />
      </q-page-container>
    </q-scroll-area>
  </q-layout>
</template>
<script>
import { defineComponent, ref } from 'vue'
import { useUI } from 'stores/ui'

export default defineComponent({
  name: 'MainLayout',
  setup () {
    const ui = useUI()
    const scrollPageRef = ref(null)

    ui.$onAction(({ name, args }) => {
      switch (name) {
        case 'setScrollPosition':
          scrollPageRef.value.setScrollPosition(args[0], args[1], args[2])
      }
    })
    return {
      scrollPageRef,
    }
  },
})
</script>
  1. components/SomeComponent.vue Create the component from where you want to call scoll action.
<template>
  <q-page-sticky position="bottom-right" :offset="[18, 18]">
    <q-btn @click="scrollToTop" fab icon="keyboard_arrow_up" />
  </q-page-sticky>
</template>
<script>
import { useUI } from 'stores/ui'
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'BackToTopComponent',
  setup () {
    const ui = useUI()
    const scrollToTop = () =>{
      ui.setScrollPosition('vertical', 0, 250)
    }
    return {
      scrollToTop,
    }
  },
})
</script>

  1. pages/SomePage.vue Create your page
<template>
  <q-page>
    <div id="some-page-content"></div>
    <some-component/>
  </q-page>
</template>

<script>
import { defineComponent } from 'vue'
import SomeComponent from 'components/SomeComponent.vue'

export default defineComponent({
  name: 'SomePage',
  components: {
    SomeComponent,
  },
})
</script>
<style scoped>
#some-page-content {
  height: 500vh;
}
</style>
  1. router/routes.js add your route
const routes = [
  {
    path: '/test',
    component: () => import('layouts/MainLayout.vue'),
    children: [
      {
        path: '',
        component: () => import('pages/SomePage.vue'),
      },
    ],
  },
]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Rougeron
Solution 2
Solution 3 mkungla