The Vue 3 composition API does not allow for the return of values from helper functions to components

It seems that there may be a scope issue within my helper function. I have successfully implemented the same logic in my component and it works flawlessly.

I have already utilized a composable function to incorporate ref() with the variable that needs to be returned.

=> This is the functioning code within my component

// component.vue
setup() {
    const subnavDiv = ref(false) // this variable gets updated by the code below

    onMounted(() => {
      const routEl = document.querySelector('.main')
      const fixedNav = document.querySelector('.main-nav')
      const el = document.querySelector('.search')

      let prevYPosition = 0
      let directionVar = 'up'
      const options = {
        root: routEl,
        rootMargin: `${fixedNav.offsetHeight * -1}px`,
        threshold: 0.7
      }

      const setScrollDirection = () => {
        if (routEl.scrollTop > prevYPosition) {
          directionVar = 'down'
        } else {
          directionVar = 'up'
        }
        prevYPosition = routEl.scrollTop
      }

      const onIntersection = ([e]) => {
        setScrollDirection()
        if ((directionVar === 'down' && e.boundingClientRect.top > 0) || !e.isIntersecting) {
          console.log('down')
          subnavDiv.value = true
        } else {
          subnavDiv.value = false
        }
        if (
          e.isIntersecting &&
          (e.boundingClientRect.top < fixedNav.offsetHeight ||
            e.boundingClientRect.top > fixedNav.offsetHeight)
        ) {
          subnavDiv.value = false
        }
      }

      const observer = new IntersectionObserver(onIntersection, options)
      observer.observe(el)
    })

    return {
      subnavDiv
    }
  }
}

=> After moving the same code out of the component

// component.vue
setup() {
    const subnavDiv = ref(false)

    onMounted(() => {
      const rootEl = document.querySelector('.main')
      const fixedNav = document.querySelector('.main-nav')
      const el = document.querySelector('.search')

      subnavDiv.value = onIntersect(rootEl, 0.7, fixedNav, el) // Function call for the helper function: The purpose of this line is to update the value of subnavDiv
    })
})


///////////////////////  $$$$$$$$$$$$$$$$$$  ///////////////

onIntersect.js // The helper function
const onIntersect = (rootElement, thresholdValue, elementToChange, elementToWatch) => {
  let prevYPosition = 0
  let directionVar = 'up'
  const options = {
    root: rootElement,
    rootMargin: `${elementToChange.offsetHeight * -1}px`,
    threshold: thresholdValue
  }
  let bool = false // The variable I am attempting to return from this function

  const setScrollDirection = () => {
    if (rootElement.scrollTop > prevYPosition) {
      directionVar = 'down'
    } else {
      directionVar = 'up'
    }
    prevYPosition = rootElement.scrollTop
  }

  const onIntersection = ([e]) => {
    setScrollDirection()
    if ((directionVar === 'down' && e.boundingClientRect.top > 0) || !e.isIntersecting) {
      console.log('down')
      bool = true
    } else {
      bool = false
    }
    if (
      e.isIntersecting &&
      (e.boundingClientRect.top < elementToChange.offsetHeight ||
        e.boundingClientRect.top > elementToChange.offsetHeight)
    ) {
      bool = false
    }
  }

  const observer = new IntersectionObserver(onIntersection, options)
  observer.observe(elementToWatch)

  return bool // The return statement (not returning anything)
}

export default onIntersect

Answer №1

The main focus is on the reference aspect of the pattern, where values are passed between scopes by reference. The onIntersect function should adhere to standard composable conventions and be called within setup rather than lifecycle hooks.

In Vue, direct DOM manipulation is discouraged. If components like main are created within the same component, they should be template refs. Otherwise, they can be passed as refs to the composable for reactivity. Using onMounted within a composable can lead to inflexibility and race conditions, especially when accessing elements like elementToWatch.

...
const rootElRef = ref(null);
const isSubnav = useIntersect(rootElRef, ...);
onMounted(() => {
  rootElRef.value = document.querySelector('.main');
  ...

This setup allows for immediate access to DOM elements if necessary, but they are still treated as refs. Additionally, it can respond to parameter changes, such as refreshing the observer if options need adjustment.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A recursive function in ECMAScript 6 using promises

I am currently in the process of developing a foundational class for sequelize.js. This particular class will handle the association of all related tables, with the includeFk function responsible for executing this task. The function involves the use of pr ...

Struggling with sending form data to the back end when uploading images in Angular

I've been facing a challenge trying to implement profile picture upload alongside standard text data and sending it all to the backend to create a new user through mongoose. Despite my efforts, using tools like ng-file-upload/angular-file-upload and e ...

What method is most effective for iterating through ajax requests?

Currently, I am working on Sharepoint and have developed an app that generates lists within the site collection. The process of creating the list is not a challenge for me. However, my goal is to create 15 columns and incorporate them into the default view ...

What are the advantages of retrieving a complete category tree, including all categories and sub-categories, versus retrieving only the necessary branches as required?

My query is not centered around terminology accuracy, but rather on the goal of presenting a tiered structure consisting of categories, sub-categories, and sub-subcategories. In total, there are approximately 100 different categories and their respective ...

Header on top of table that stays in place with scrolling

I'm facing an issue with a table that contains user-generated data. We are utilizing a plugin known as Clusterize, which allows us to smoothly scroll through large amounts of rows. However, the specific markup required for this plugin seems to be caus ...

What is preventing me from loading a module using a variable containing a string?

This code snippet demonstrates how the module can be successfully loaded using import('test'), but not with the second example. These lines of code are executed within an Angular 9 application utilizing the default Webpack configuration. var tes ...

Running an npm audit on the project reveals numerous errors and vulnerabilities

After running npm audit on my React project, I was presented with an extensive list of issues that needed attention. # npm audit report postcss 7.0.0 - 8.2.9 Severity: moderate Regular Expression Denial of Service - https://npmjs.com/advisories/1693 fix ...

Stripping CSS from my HTML using TinyMCE

I have created a custom Javascript function that retrieves the content of an HTML file from my server and then integrates it into a TinyMCE editor. Here is the function: function LoadTemplate(url) { $.post(url, function (data) { // Access the ...

Continuously running React useEffect even with an empty dependency array

In my React application, I have implemented a hook system. Each sub-hook that is generated within this main hook is assigned a unique ID automatically. This ID is incremented by 1 every time a new sub-hook is created, ensuring uniqueness. const App = ...

What specific files from the Kendo core are required for utilizing Mobile and Angular functionalities?

After browsing through similar questions, I couldn't find a solution. Currently, I am experimenting with Kendo (open source core for now) in a Visual Studio Cordova project. Initially, disregarding Cordova, I am focusing on setting up a basic view wit ...

Configuration file included in Node.js package for distribution

Someone recommended incorporating Continuous Integration for a pre-existing application (FrontEnd: Node.js - BackEnd: .Net API). At the moment, the API endpoints are hardwired in the .js files which become minified after being built using webpack. I plan ...

Enlarging and cutting video footage

I have developed an app that features a code enabling users to capture photos using their computer-connected camera. How it Works: A webcam is utilized to display a video element with the camera as its source: function onSuccess (stream) { this.video.s ...

Trouble with jQuery addClass function when trying to add to a specific object variable

I'm attempting to give an error class to an input textbox to inform the user that their input is invalid. Within the change event, I am referencing what seems to be the input field and storing it in a variable. However, calling addClass on the var ...

Implementing Bootstrap JavaScript functionality within a Rails 7 application

My current Rails 7 application utilizes esbuild as the JS bundler and has bootstrap imported. I am facing an issue where I am unable to access any Bootstrap Javascript functionality outside of the main application.js file. For example, I am attempting to p ...

The Jquery Ajax .load() function is not working properly

<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Tabs - Expanding content</title> <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> < ...

Exciting jQuery animations and transitions

Is there a way in JavaScript to call function or method names using a string? For example, when writing jQuery code that applies an effect to specific targets, can the effect be dynamic and changeable by the user? I'm hoping for something like jQuer ...

jQuery behaving erratically following deployment to the testing server

I am encountering an issue with jQuery in a user control that utilizes a Telerik RadGrid: <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.js"></script> <script type="text/javascript"> ...

Issue: Receiving an error message stating "Text data outside of root node" while attempting to install a

At times, I encounter an error when attempting to install any cordova plugin with Ionic (typically after 6pm GMT+0). These errors occur with plugins sourced from both npm and GitHub, and the message I receive is: Error: Text data outside of root node. Li ...

Query parameter is not defined

Can anyone assist me with extracting the ean from the following URL: This NodeJS server processes the request in the following manner: const http = require('http') const port = 3000 const requestHandler = async (request, response) => { ...

Rendering based on conditions with a pair of values

I am trying to render my component only if the id is equal to either 15 or 12. My current approach is not working as expected, it only renders the component when I check for one id at a time, but I need to check for both. {query_estate_id === 15 || q ...