When a Vue3/Vuex object created using reactive() is used as a payload in a mutation to Vuex, it loses its reactivity

Ever wondered why you might need a reactive object compatible with Provide/Inject for your Vuex Store? Well, it's all about flexibility and functionality!

Picture this: you have a plugin for authentication that needs to be integrated into your app. By utilizing a "caveman style" vuex plugin function, you can easily register it within the namespaced User module of your vuex store. The catch? Once registered, the reactivity of the object is lost within the store while Provide/Inject continues to operate seamlessly.

If code speaks louder than words, take a look at the following snippets:

AuthLink.vue

...

export default defineComponent({
    setup() {
        const auth = inject("Auth") as IAuthPluginProperties;

        async function logInFromLink(
            withPopUp = false,
            options?: {
                redirectLoginOptions?: RedirectLoginOptions;
                popupConfigOptions?: PopupConfigOptions;
                analytics: undefined;
            }
        ): Promise<void> {
            if (withPopUp) return auth.loginWithPopup();

            //* Add analytics for tracking link-based logins.

            return await auth.loginWithRedirect(options?.redirectLoginOptions);
        }

        function logout(logoutOptions?: LogoutOptions): void {
            auth.logout(logoutOptions);
        }

        return {
            auth,
            logInFromLink,
            logout
        };
    }
});
</script>

Ready to dive deeper? Let's explore the functionalities in the plugin implementation:

Plugin - index.ts

...
export default {
    install: async (app: App, options: pluginInstallOptions): Promise<void> => {
        app.config.globalProperties.$auth = Plugin.AuthPluginProperties;
        app.provide("Auth", Plugin.AuthPluginProperties);

        /*
         * Handle defaults from .env vars
         */

        

        if (options.useStore) {
            if (!store.hasModule("User")) {
                throw new Error("🙈🙉🙊 Looks like something is off... 'User' vuex store module is missing.").stack;
            }

            await vuexPlugin(store, Vue3AuthPlugin.AuthPluginProperties);
       
...

Sneak peek into the main.ts file showcasing essential properties:

...

const state = reactive({
    isLoading: false,
    isAuthenticated: false,
    user: undefined,
    popupOpen: false,
    error: null
}) as IAuthStateProp;

export const AuthPluginProperties = reactive({
    isAuthenticated: computed(() => state.isAuthenticated),
    isLoading: computed(() => state.isLoading),
    user: computed(() => state.user),
    // more functions included here
}) as IAuthPluginProperties;

...

Update! Don't miss out on the implementation of the "caveman style" vuex plugin function:

auth-vuex-plugin.ts

import { AuthVuexPlugin } from "../types";

const plugin: AuthVuexPlugin<Record<string, unknown>> = async (store, payload) => {
    try {
        await store.dispatch("User/INITIALIZE_PLUGIN", payload);
    } catch (err) {
        throw new Error(`🙈🙉🙊 Oops... Something went wrong with Vuex initialization: ${err}`);
    }
};

export default plugin;

Answer â„–1

Successfully accomplished my goal by passing the payload as ToRefs(payload) and typed it with Vue's generic ToRefs like ToRefs<IAuthState>.

I'm not completely certain if this is the most optimal approach, but I'm open to suggestions or improvements if anyone wants to join me on this journey :)

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

The alignment of Bootstrap table headers in a Vue.js component needs adjusting for better display

Is there a way to ensure proper alignment of headers and column bodies in my Vue.js DataGrid component when utilizing the vuedraggable package for column reordering? Below is the code snippet for my DataGrid.vue component: <template> <div class ...

Creating a VSCode extension using Vue: Step-by-step guide

I'm looking to develop a VSCode extension with Vue utilizing the VSCode webview. However, when attempting to import the compiled index.html into my extension, I consistently receive a prompt to enable JavaScript. Is there a solution for integrating Vu ...

Unfortunately, an exception was encountered: ES Module must be loaded using the import statement

Currently, I am addressing some vulnerability concerns within my Angular development environment. These vulnerabilities are found within internal dependencies, so I have included resolutions in the package.json file. However, when I attempt to run 'ng ...

Apache ECharts is throwing an error due to incompatible types of the 'trigger' property

I am experimenting with setting up some options in this demonstration, and here is what I have managed to achieve so far. testOptions: EChartsOption = Object.assign( {}, { backgroundColor: 'red', tooltip: { trigger: ...

Having trouble retrieving a value from a reference object in React Typescript?

Struggling with a login form issue in my React TypeScript project. Below is the code for the react login form: login-form.tsx import * as React from 'react'; import { Button, FormGroup, Input, Label } from 'reactstrap' ...

Speaking about the `this` Vue component in an event listener context

Consider this Vue component that is equipped with a global event listener: let myApp = new Vue({ data: { foo: 0; }, methods: { handle: function(event) { this.foo = 1; // 'this' pertains to the handler, not ...

What is the best way to integrate content from the tiptap text editor into a v-model?

Trying to directly bind this.newTutorial.content to editor.content, but no success so far. Console output: https://i.sstatic.net/BNRR4.png Code snippet: <style scoped> img.preview { width:200px; } .v-btn { height: 50px !important; min-wi ...

Retrieve the name of a component using a Vue directive

I am looking to create a customized Vue directive that allows me to select specific components on my page for hydration. Essentially, this is the goal I am striving to achieve: I want to render my Vue application on the server (ssr) I plan to attach a ...

Bypass VueJs Typescript errors within the template section with Typescript

My VueJs App is functioning properly, but there is one thing that bothers me - a TypeScript error in my template block. Is there a way to handle this similar to how I would in my script block? <script setup lang="ts"> //@ignore-ts this li ...

Testing a Vue.js/Node.js application using Websockets

I'm working on a Vue project (version 3.0.3) integrated with a Node.js server. Can you provide guidance on how to conduct unit testing for this setup? The application is a game that relies on web-sockets for communication. ...

Retrieve the previous URL for redirection purposes

I have a specific route set up in my application. If the user is not logged in, they are redirected to the login page. I am currently working on capturing the previous route that the user came from so that I can redirect them back there after they have suc ...

How can JavaScript transform Unicode strings?

<i class="icon">&#xe672;</i> This code will display an icon like this: > However, when I render it in Vue: <i class="icon">{{a}}</i> a = '&#xe672;' The result is  It displays as a string! ...

Having difficulty maintaining trailing zeroes in decimals after converting to float in Angular

I need assistance with converting a string to float in Angular. Whenever I use parseFloat, it seems to remove the zeros from the decimal values. How can I ensure that these zeros are retained with the numerical values? The example below should provide more ...

Modifying the title of a tab in Chrome with Vue: A step-by-step

What is the process for customizing the tab title of a Vue.js application from "Webpack App"? https://i.sstatic.net/jlERs.png ...

discovering a new type of mutation through the use of Vuex

Vue Component computed: { score () { this.$store.commit('fetchCoordinates'); console.log(this.$store.getters.cordinate); } } store.js export default { state: { lat:'ok', }, getters:{ cordinate(state){ r ...

Utilizing Lodash debounce in VueJs watch feature while incorporating Typescript

When working with VueJS in Javascript, I can achieve the following: import debounce from "lodash/debounce"; ... watch: { variable: debounce(function() { console.log('wow'); }, 500) } However, when attempting to do the same in VueJS us ...

Finding the number of elements in a FirebaseListObservable involves accessing the `length` property

One of the tasks in my Angular 2 application involves retrieving data from a Firebase database and storing it in a FirebaseListObservable. I have a method called getStatus that is supposed to determine the number of elements in this FirebaseListObservable. ...

Getting event properties in a React component using the rest operator: A comprehensive guide

Can someone please assist me? I am new to TypeScript and struggling with how to use event props in my component. I have defined two props and need all my events as rest props. I encountered an error when trying to use my component with onClick event. The ...

Enhance the collapsible feature in Vue.js by integrating Bootstrap and anim

In the process of creating a side bar menu with collapse show/hide functionality, I am encountering some issues. The current CSS implementation is making the collapse action appear abrupt and unnatural. I am looking to achieve a smooth sliding transition ...

The second click does not impact the props received by the child component

I created a basic app with a link to the code. The child component receives props like this: props: ['isActive'], and then it changes its value to display a modal window: data: function() { return { isActive: this.isActive // value from pr ...