Managing data in Vue3 with multiple instances of Composition API data store allows for separate

Consider simplifying a practical scenario...

Imagine having a web application with two columns, each utilizing the same component. The functionality is based on data storage and functions that are stored in a separate composition api js file, which is then imported into the component via provide/inject. It works seamlessly.

However, is there a way to write the composition api js file once, and then generate multiple instances when it's imported to the Vue app? This would allow for individual instances to be assigned to each component without sharing the same data object. I understand that if you import the same file using different names...

import instanceone from "path";
import instancetwo from "path";

...they end up sharing the same objects because they are essentially importing the same file under different names, not creating distinct instances of the file.

Is there a method to achieve this desired outcome? I'm open to any approach that can lead to the same result (without requiring duplicate files for independent usage). One idea was to create a single file that exports objects and functions, followed by two separate files that import specific components of the initial file, and finally letting Vue import these two files - but unfortunately, it did not work as expected.

While there are numerous other ways to tackle this issue, I am intrigued by exploring this particular possibility first, preferably without relying on Vuex.

Thank you!

Answer №1

Here is a method to achieve the desired outcome:

/* composable_module.js */

import { ref, computed } from 'vue';

export const shared_var_1 = ref(0);
export const shared_var_2 = ref(0);

export function composable_variables() {
 // This function will provide separate instances of variables for each function call
 const var1 = ref(0);
 const comp_var1 = computed(() => var1.value + shared_var_1.value);
 // comp_var1 will update its value when either var1 or shared_var_1 values are updated
 return { var1, comp_var1 };
}

Example usage:

/* component_1.vue */
import { shared_var_1, shared_var_2, composable_variables } from 'composable_module.js';


/* Any additional setup required for the component or file */
setup() {
 const { var1, comp_var1 } = composable_variables();
 /*
 Perform actions with
 shared_var_1, shared_var_2, var1, comp_var1
 */
 // Return any data needed for the template
 return { shared_var_1, shared_var_2, var1, comp_var1 }
}

In this context, shared_var_1 and shared_var_2 serve as Vuex store values, while var1 and comp_var1 are unique for each function call. This allows them to be utilized in various components as distinct variables sharing common functionality without sharing their values.

Answer №2

In the 'path' composable, you have the option to define two states and then choose the appropriate state using code like this:

const { getItem1, getItem2, setItem1, setItem2 } = (whichInstance) ? instanceOne : instanceTwo

All you need to do is set up your whichInstance condition to pick the desired instance.

Your composable structure might look something like this:

const stateOne = reactive({
    item1: true,
    item2: 1
})

const stateTwo = reactive({
    item1: false,
    item2: 2
})

export function instanceOne() {
    let stateRef = toRefs(stateOne)

    /* Getters */
    const getItem1 = () => {
        return stateRef.item1
    }
    const getItem2 = () => {
        return stateRef.item2
    }

    /* Mutations */
    const setItem1 = (value) => {
        stateRef.item1.value = value
    }
    const setItem2 = (value) => {
        stateRef.item2.value = value
    }

    return {
        state: toRefs(stateOne),
        getItem1,
        getItem2,
        setItem1,
        setItem2
    }
}


export function instanceTwo() {
    let stateRef = toRefs(stateTwo)

    /* Getters */
    const getItem1 = () => {
        return stateRef.item1
    }
    const getItem2 = () => {
        return stateRef.item2
    }

    /* Mutations */
    const setItem1 = (value) => {
        stateRef.item1.value = value
    }
    const setItem2 = (value) => {
        stateRef.item2.value = value
    }

    return {
        state: toRefs(stateTwo),
        getItem1,
        getItem2,
        setItem1,
        setItem2
    }
}
})

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

When render returns another component, React does not invoke componentWillMount

Here is my code setup: const Dashboard = React.createClass({ getInitialState(){ return { user: JSON.parse(localStorage.getItem('user')) }; }, componentWillMount(){ var self = this; $.get({ url: 'http://127 ...

Gather all possible routes within the JSON structure

I am faced with a JavaScript object that contains various data: { "gender": "man", "jobinfo": { "type": "teacher" }, "children": [ { "name": & ...

The React JSX error message "Maximum update depth exceeded" occurs when there

It appears that I am facing an issue of creating an infinite loop while passing props from one class to another. Despite ensuring that the buttons are correctly bound and trigger only once, the problem persists without any solution in sight after thorough ...

What is the best way to eliminate the left padding on a TimelineItem component?

When using the Timeline component to display information, there are three columns: TimelinItem, TimelineSeparator, and TimelineContent. I tried setting the padding of TimelineItem to 0 but it didn't work. The <Trace/> component is a sub-compone ...

The Handsontable namespace does not include the _editors module in its exports

While following the documentation, I encountered an error when trying to integrate handsOnTable with my Vue 2 project using npm. The build process failed with the following message: ERROR in /node_modules/@handsontable/vue/types.d.ts(56,73): 56:73 Namesp ...

What is the best way to display a component in Vue.js only when the user is redirected from a specific page?

Like the title suggests, I am looking to have a message appear only if the page is redirected from a specific page. I believe it may be related to either this.$router or this.$route, but I'm having trouble figuring it out. ...

The concept of self-referencing in TypeScript

I recently developed a Vue plugin that allows me to easily access constant objects in the templates of .vue files using shortcuts: <template> <span>{{ $consts.HELLO }}</span> </template> export default { constants: {HELLO: ...

Error: Could not locate local grunt on Windows 7 Professional

When attempting to initiate grunt, an error message is displayed: c:\repositories\kunde_1\themes-projekt_1\projekt_1-responsive\source>grunt grunt-cli: The grunt command line interface. (v0.1.13) Fatal error: Unable to find lo ...

Error: The specified function (0, _ignore.getFileExtensions) is not a valid function

Using Vue CLI version 3.5.5 After installing vue-cli and creating a new project with the create command, an error occurred at the end of the process. What steps should be taken to resolve this issue? ? Please select a preset: Manually choose features ? ...

What is the process for employing a template in Vue3 as opposed to utilizing the native template?

I'm currently working on creating a custom SelectBox component <Options> <Option v-for="person in people" :value="person" > {{ person.name }} </Option> </Options> My goal is to have the Op ...

Application with Single Page design has a Large DOM, leading to sluggish performance

I've been working on a single page application that heavily relies on widgets like grids and tabs from the jqWidgets library. These widgets are all loaded when the page is first opened. However, I've noticed that after interacting with the site f ...

Using Vue.js: Ways to recycle a template within a component without needing to export it as a separate component

At times, there may be a need to reuse a template within a component without being able to iterate through them due to non-sequential rendering. Take for example: <template> <div> <template> <span>{{yearly.tex ...

Changing global properties in VueCli

Recently, I integrated a component library into my Vue 3 project. All instances of the component require the same styles. Instead of manually adjusting each instance's props, I opted to utilize a global property: app.config.globalProperties.$tooltipS ...

The tooltip in Amcharts malfunctions when incorporating the DurationAxis

I've been grappling with getting tooltips to work in amCharts4 when using a DurationAxis(). It seems like there might be a bug, as the tooltips sometimes get stuck in the top left corner. Here's an example: https://jsfiddle.net/jamiegau/fpye3bkv ...

Preserve the values of checkboxes throughout the entire website by utilizing localStorage

Example A functionality in the example allows users to add images to a container by clicking on checkboxes. However, there is an issue where when a checkbox is checked on one page to store an image, and then another checkbox is checked on a different page ...

What steps do I need to take in order to make the navbar-collapse function properly with an animated

After successfully implementing a collapsible navbar with a hamburger icon for mobile view, I decided to add some extra styling and animation to the hamburger button. However, now the hamburger button remains visible even in desktop view, which is not what ...

Displaying vue-i18n output in the Quasar data-table title field

Integrating vue-i18n with quasar-framework in vue I am seeking guidance on how to incorporate the $t('message.hello') function, whether it should be placed within a v-html tag or within double braces like {{ $t('message.hello') when st ...

Angular is not yet able to identify the $resource framework

I have implemented ngResource into my app's module: angular.module('confusionApp', ['ui.router', 'ngResource']) Then, I added the $resource dependency to my service: angular.module('confusionApp') .consta ...

When was Chrome first updated to include timezone offset support for Intl.DateTimeFormat()?

My experience with Chromium 121 has been positive using the Intl.DateTimeFormat as shown below: new Intl.DateTimeFormat('en', { dateStyle: 'long', timeStyle: 'long', timeZone: '+0500', }).format ...

Guide to ordering two arrays using a common randomized sorting method

Currently, I am working on a quiz application using jQuery and JavaScript. In the code snippet below, I have a function that is supposed to randomize a set of possible answers for a question along with corresponding photos. Each photo matches one of the a ...