Composition-api: react to vuex computed values

Created on 5 Jan 2020  路  9Comments  路  Source: vuejs/composition-api

Dear Sirs,
I'm trying to use vuex with composition API, I have some computed values from the store my components must reflect.
My problem is that i don't understand the reason why if i use

setup(props,{root}) {
    var store =  useStore().state;
        const changing_view = computed(() => store.main_store.changing_view);
}

my component correctly reacts to 'changing_view' values

while if i try to do something like

setup(props,{root}) {
    var store =  useStore().state;
        const changing_view = computed(() => store.main_store.changing_view);
        const state = {
              changing_view:changing_view
        }
}

the component is not reacting anymore to state.changing_view.
What should i do to centralise my computed values exporting only the state object and work on that?
Do you have any hint on this?

Thank you

All 9 comments

It would be helpful to Unserstand how you actually use the state

For example... v-if="state.changing_view"

Since you added the ref to the prop of a non-reactive object, it can't be unwrapped. You have to do:

<div v-if="state.changing_view.value">

There are also some limitations due to Vue 2 reactivity, from what I've seen (I could be doing it wrongly). Eg, you cannot do:

// in Vuex

state = {
  someMap: {},
}

mutations = {
  update() {
    state.someMap['key'] = { foo: 'bar' }
  }
}

// in component
computed(() => state.someMap) // not reactive even if you commit update mutation

state.someMap['key'] = { foo: 'bar' }

yeah that's a usual Vue 2 Reactivity caveat

Hello Linus,
thank you for your answers,
I'm trying my best to make anything works as expected but also using the simplest implementation I stille getting strange behaviours.

This is my actual component script:

import Vue from 'vue';
    import VueCompositionApi from '@vue/composition-api';

    Vue.use(VueCompositionApi);

    //import  { useStore } from 'vuex';
    import useStore from '@/store';

    import { 
          computed

    } from '@vue/composition-api';

    export default {
        name: 'topnav',
        setup(props,{root}) {

            var store =  useStore().state;




            const changing_sub_area = computed(() => store.main_store.changing_sub_area);
            const logo = computed(() => store.main_store.topnav_config['logo_'+store.main_store.main_config.software_package_name]);
            const changing_view = computed(() => store.main_store.changing_view);
            const loading_content = computed(() => store.main_store.loading_content);
            const area_sub = computed(() => store.main_store.area_sub);
            const open_side_nav = computed(() => store.main_store.open_side_nav);




            //console.log(state);

            const toggleSideNav = function () {
                root.$store.commit('main_store/TOGGLE_SIDE_NAV');
            }


            return {
                changing_sub_area,
                logo,
                changing_view,
                loading_content,
                area_sub,
                open_side_nav,


                toggleSideNav
            }

        }
    }

I don't get errors or warnings, what is happening is that computed values stay the same till I navigate the app a bit and hit refresh, from that moment the component and the value starts to react correctly.
Once computed values start to react to store changes it keep working correctly even if i refresh the browser.
It's a very weird behaviour, cannot get why it happens.
Hope you can help me.
Thank you

That code looks all fine. But you didn't provide the acual template usage or the store implementation (what exatly does useStore do?), the mutations doing the changes etc.

This seems surely to be a usage problem, so I kindly ask you to use forum.vuejs.org or chat.vuejs.org to ask for help. I don't see anything that seems like a bug.

Basically my app does an ajax call to get general configs like "logo" for example, once I get the response i set with a mutation my store state, I expect my component to get the new value.

here is my store code:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

import main_store from '@viso/store_functions/modules/main_store';
import booklets_store from '@viso/store_functions/modules/booklets_store';
import subjects_store from '@viso/store_functions/modules/subjects_store';
import viewsconfigs_store from '@viso/store_functions/modules/viewsconfigs_store';
import forms_store from '@viso/store_functions/modules/forms_store';

export default function createStore() {
    return new Vuex.Store({
        modules: {
            main_store,
            booklets_store,
            viewsconfigs_store,
            subjects_store,
            forms_store
        }
    });
}

import { getCurrentInstance } from '@vue/composition-api'

export function useStore() {

    const vm = getCurrentInstance();

    return vm.$store

}

i need createStore function because I'm implementing vapper.js

This seems surely to be a usage problem, so I kindly ask you to use forum.vuejs.org or chat.vuejs.org to ask for help. I don't see anything that seems like a bug

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sapphi-red picture sapphi-red  路  4Comments

SJanJan picture SJanJan  路  3Comments

mbbbc picture mbbbc  路  6Comments

kwanjas3 picture kwanjas3  路  4Comments

banricho picture banricho  路  3Comments