Mastering Inter-Composable Communication in Vue 3: A Guide

Composables in Vue documentation demonstrate how small composition functions can be used for organizing code by composing the app.

Discover More About Extracting Composables for Code Organization

"Extracted composables act as component-scoped services that interact with each other."

When working with multiple composables, a common question arises: How can you communicate between them? Specifically, how do you modify a variable (ref) located within another composable? Imagine building an application with two composables - users and statistics. The challenge is altering the selectedUser from within the loadStatistics method with no direct access available. What approach should be taken to handle this situation effectively?

ShowStatistics.vue

<template>
  <select v-model="selectedUser">
    <option v-for="user in users" :value="selectedUser">
      {{ user }}
    </option>
  </select>

  <button @click="loadStatistics">
    Load Statistics
  </button>
</template>

<script setup lang="ts">
    const { users, selectedUser } = useUsers()
    const { loadStatistics } = useStatistics()
</script>

useUsers.ts

import { ref } from 'vue'

export function useUsers() {
    const users = ref([])
    const selectedUser = ref({})

    users.value = UsersApi.getUsers()

    return { users, selectedUser }
}

useStatistics.ts

export function useStatistics() {
    const loadStatistics = () => {
        window.store.statistics = StatisticsApi.loadStatistics()
        
        selectedUser = window.store.statistics.user
           // ^~~~~~~~~~~~~~~ ERROR: selectedUser is not defined
    }

    return { loadStatistics }
}

Answer №1

To make use of the selectedUser ref in the useStatistics() function, you can pass it as an argument:

ShowStatistics.vue:

<script setup lang="ts">
    const { users, selectedUser } = useUsers()
    const { loadStatistics } = useStatistics(selectedUser)
</script>

useStatistics.ts:

                                   👇
export function useStatistics(selectedUser) {
    const loadStatistics = () => {
        window.store.statistics = StatisticsApi.loadStatistics()
                 👇
        if (selectedUser) {
            selectedUser.value = window.store.statistics.user
        }
    }

    return { loadStatistics }
}

Answer №2

After extensive research and not finding any examples in the official documentation, I stumbled upon a solution to return a derived state in order to monitor it later within the useStatistics composable. If anyone has a more efficient approach, please feel free to share. For now, this is the most optimal solution I have come across.

This method also addresses the issue of tight coupling when attempting to directly modify the selectedUser from within the useStatistics composable, which goes against the intended purpose of creating these composables.

export function useStatistics(selectedUser) {
    const selectedUserStatistics = ref(selectedUser)

    const loadStatistics = () => {
        window.store.statistics = StatisticsApi.loadStatistics()

        selectedUserStatistics.value = window.store.statistics.user
    }

    return { loadStatistics, selectedUserStatistics }
}

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

What is the best approach for creating a test that can simulate and manage errors during JSON parsing in a Node.js

My approach to testing involves retrieving JSON data from a file and parsing it in my test.js file. The code snippet below demonstrates how I achieve this: var data; before(function(done) { data = JSON.parse(fs.readFileSync(process.cwd() + '/p ...

React - How to Close Material-UI Drawer from a Nested Menu

Currently, I am utilizing a fantastic example (here) to create a dynamic nested menu for my application. Taking it a step further, I am trying to integrate it into a Material UI appbar/temporary drawer. My goal is to close the drawer when the user clicks o ...

What are the steps for incorporating the AAD B2C functionality into an Angular2 application with TypeScript?

I recently built a web application using Angular2 and TypeScript, but now one of my clients wants to integrate Azure B2C for customer login instead of OAuth. I followed a simple example on how to implement Azure B2C in a .NET Web app through the link provi ...

Simulate mobile double tap screen resize using either jQuery or Javascript

UPDATE: I have encountered an issue that requires assistance. I am seeking help with implementing a functionality to automatically resize screen contents on mobile devices by calling a DoubleTap. The reason behind this requirement is that when a script up ...

A guide on utilizing the .getLastRow() function in Google Apps Script

I am relatively new to Google Script and I am currently working on a piece of code that is giving me some trouble. My goal is to have the program loop through a range of cells in a spreadsheet, printing them out until it reaches the last row. Despite try ...

What is the best way to fetch a partial JSON response object from an API using JavaScript?

Currently, I am utilizing the One Bus Away API, returning a response object in this format: { "code": 200, "currentTime": 1504150060044, "data": { "entry": { "arrivalsAndDepartures": [ {AnD_item1 ...

React Virtualized - Blank screen issue occurring because of continuous scrolling through a large list of ITSM items

I am currently working on a lengthy list of items and utilizing the react-virtualized library for this purpose. However, I have encountered an issue that needs addressing. https://i.stack.imgur.com/ROdjp.gif Upon attempting to scroll down for 2 seconds, ...

The issue with Jquery Lightbox/Modal doubling upon clicking

Having just started with jQuery, I've encountered an issue with my Gallery Lightbox/Modal. Whenever I click on a thumbnail, the modal reopens itself and I'm unsure where to set a reset. Any help would be greatly appreciated. jQuery(function($) { ...

Selected value is not displayed in the textbox when using autocomplete feature

---Ajax---- An issue has arisen with the autocomplete feature. While typing "wi" (for example, wipro), the drop-down list appears as expected. However, if only "wi" is selected in the text box, $(document).ready(function () { $("#company_name").key ...

Express.js - Monitoring for server closure

I have a Node.js application that utilizes Express. Within this application, there is a section of code structured as follows: const app = require('./app'); const port = process.env.PORT || 8080; const server = app.listen(port); server.on(&apos ...

How to make an Ajax "POST" request to the server using jQuery or AngularJS without sending any parameter data

"Execute a 'POST' request to the server by using the code provided below However, the parameter data is not being sent to the server. I have attempted both the jQuery Way and var request = $.ajax({ url: baseUrl, type:'post', da ...

Organize every rectangle and text element in D3 into distinct groups

Currently, I am working on creating a bar graph using d3.js. The goal is to display text on top of each bar when the user hovers over it. To achieve this, the <text> and <rect> elements need to be grouped inside a <g> element. For Exampl ...

Tips for activating just a single event, whether it's 'change' or 'click'

I am facing an issue with a number input tag that has two event listeners 'on-click' and 'on-change'. Whenever I click on the arrow, both event listeners get triggered. I want only one event to trigger first without removing any of the ...

Split domain names for images using a JQuery plugin

Recently, I came across an interesting article by Stoyan Stefanov on JS domain sharding for image files. After reading it, I felt inspired to enhance the concept and create something new. The script below is designed to go through all the images on a page ...

Creating auto serial numbers in the MERN stackWould you like to know how to

I need help coming up with a way to automatically generate serial numbers for my "ticketno" field. Every time a user creates a new application ticket, the ticket number should increment by one. Can someone guide me on how to achieve this? This i ...

Utilizing Images with 'General Drawing' in Highcharts

I'm currently attempting to create a task diagram using Highcharts. I had the idea of incorporating images using the <img> tag ren.label('<img src="/images/test.jepg', 10, 82) .attr({ ...

Conceal YouTube upon opening any model or light box

I have a YouTube video in the center of my page, and when I click on any link from the side navigation, a lightbox appears. However, in IE, the lightbox is behind the YouTube video. I have tried setting the Z-index, but it doesn't seem to work. Is the ...

Enable only the current week days on the multiple date picker feature

Can anyone recommend a date picker that only shows the current week and allows for multiple date selections by the user? I found this jsfiddle which limits the display to the current week, but it doesn't support selecting multiple dates. I attempted ...

Leverage Express JS to prevent unauthorized requests from the Client Side

Exploring the functionalities of the Express router: const express = require("express"); const router = express.Router(); const DUMMY_PLACES = [ { id: "p1", title: "Empire State Building", description: "One of the most famous sky scrapers i ...

The compatibility issues between Karma and Jasmine testing configurations cause errors during the Ionic packaging process

I've recently added testing to my ionic app using karma + jasmine, along with a typescript pre-processor. Below are the dependencies I have, most of which were added specifically for testing: "devDependencies": { "@ionic/app-scripts": "1.0.0", ...