How can I use QScrollArea with v-scroll? Or make right drower like in quasar documentation.



  • How we can combine q-scroll-area and v-scroll ?
    (to get scroll position on every scroll events)

    Or how to use q-scroll-area method getScrollPosition on every scroll event?

    I am trying to use this approach but it is not working

    <q-scroll-area 
        v-scroll="scrolled"
    >
         ...
    

    Or maybe exist another simpler approach?

    In general, I am trying to create something like this:
    on click on the right drawer item - scroll to some paragraph
    on content scroll - set active item in the drawer
    Screenshot_2.png



  • I have implemented something similar to what you probably want in my project. It is not 100% complete and tested yet. It works like this:

    DOM ids are used to define the “scroll targets” in the HTML displayed in the main window. In my case, this is HTML containing help information. I have a “table of help content” (JS object loaded from a file manually maintained along with the help HTML) which holds those ids per help topic. Those ids are at the same time defined in the HTML which makes up the help information, for example (for an id named “chapter 3”):

     <h5 id="chapter 3">3.0 Heading Text of Chapter 3</h5>
    

    In my drawer code (which is part of MyLayout.vue in case) I dynamically determine the desired DOM id based on what the user selects in that “table of help content”. That DOM id is then passed to the “help” component. The code to maintain and navigate through my “table of help content” is very specific, can’t include that here.

    The DOM id is also both part of the route of the help component (named “Hilfe”, you see, I’m German), which controls what is displayed in the main window (see code in routes.js, below), and is passed through the drawer code as a property to that help component. The code for that is in one method (part of MyLayout.vue, called by the drawer code) and is simple:

    methods: {
        setRouteAndId(id) {
          this.$router.replace("/Hilfe/" + id);
          this.selectedHelpTopicId = id;
        }
    

    The “help” component works like this: In routes.js, it is defined as follows:

    const routes = [
       {
        path: "",
        component: () => import("layouts/MyLayout.vue"),
        children: [
          /* ... other route definitions here */
          /* Route definition for help component: */        
          {
            path: "/Hilfe/:helpTopicElementIdToScrollTo",
            name: "Hilfe",
            props: true, // so called "Boolean mode", allows passing of prop :helpTopicElementIdToScrollTo to the help component through Vue router commands
           component: () => import("pages/Hilfe.vue")
          },
        ]
      }
    ];
    

    Next, as already explained, the help component has the DOM id in its props:

    import { scroll } from "quasar"; 
    const { getScrollTarget, setScrollPosition } = scroll; // Hint: Use "LPR" for <q-layout view=...>
    export default {
      name: "hilfe", // component name
      props: { helpTopicElementIdToScrollTo: String },
    

    As part of the other code for the help component, there is a method scrollToElement(elementId) to scroll to a DOM id:

        scrollToElement(elementId) {
          // Scroll function to scroll to the position defined by elementID 
          let element = document.getElementById(elementId); // Access to DOM with elementID, Vue DOM API
          let target = getScrollTarget(element);
          let offset = element.offsetTop; // Do not subtract the element.scrollHeight here
          let duration = 500; // milliseconds, scroll duration
          setScrollPosition(target, offset, duration); // Scroll to DOM position with elementId
        }
    

    In addition, ther is a watch in that help component code on the above property helpTopicElementIdToScrollTo. That watch calls the above method scrollToElement as soon as the value of helpTopicElementIdToScrollTo changes (which is usually happening through code in my drawer, if the user selects a different help topic in the table of help content):

    watch: {
        helpTopicElementIdToScrollTo: function(val) {
          /* Watch for props change of helpTopicElmentIdToScrollTo */
          this.scrollToElement(val); 
        }
    

    That’s my solution. I’m not sure it is the most elegant solution for the requirement, but it works reasonably well. As I said, I’m still testing it. The Quasar team has probably a more advanced solution as part of their documentation code showing up e.g. on https://quasar.dev/vue-components/ajax-bar (which has even two drawers interacting with the doc content in the main window).

    I realize that I’m not using <q-scroll-area> or the v-scroll directive. Maybe I should, but I’m not familiar with those.

    See also https://forum.quasar-framework.org/topic/4217/how-to-link-to-html-pages-from-drawer - this describes how I got to the above solution.


Log in to reply