Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

How to access Vue(vm) instance in Vuex store? #1399

Closed
ankitsinghaniyaz opened this issue Sep 10, 2018 · 17 comments
Closed

How to access Vue(vm) instance in Vuex store? #1399

ankitsinghaniyaz opened this issue Sep 10, 2018 · 17 comments

Comments

@ankitsinghaniyaz
Copy link

What problem does this feature solve?

I have a $notify method on Vue prototype. I need to use that in my action. Is there a way to do that?

I see that on Vuex we have this.$_vm but not sure if that is the right thing to do

What does the proposed API look like?

this.vue.$notify()

@firminochangani
Copy link

@ankitsinghaniyaz You may want to read more about "Event Bus".

https://alligator.io/vuejs/global-event-bus/

@jonaskuske
Copy link

You can pass in a vm instance as an argument, so in your component where you dispatch the action, you can call:

this.$store.dispatch('myAction', { vm: this });

Now your action can access vm on the parameter object and call $notify() on it:

myAction(context, { vm }) {
  vm.$notify();
}

@ktsn ktsn added the proposal label Oct 8, 2018
@ktsn
Copy link
Member

ktsn commented Oct 8, 2018

IMO, Vuex should not have reference to Vue instance because it is responsible for data. The approach that @jonaskuske provides looks suitable solution.

@ktsn ktsn closed this as completed Oct 8, 2018
@serkandemirel0420
Copy link

this._vm

@m00nk
Copy link

m00nk commented May 12, 2019

import App from './App.vue';

const myStore = new Vuex.Store({
    state: {
        ...
    },
    actions: {
        myAction(ctx, data) {
              // here you can use this.$app to access to your vue application
        }
    }
});

const app = new Vue({
    el: '#my-div',
    render: h => h(App),
    store: myStore
});

myStore.$app = app; // <--- !!! this line adds $app to your store object

@louisameline
Copy link

@m00nk this is undefined for me inside Vuex actions. Note that I use Quasar and have a dedicated file for actions, not sure how it would work in another configuration.

I went with another solution, passing the app in a call upon creation of the store, something like:

const app

export const storeInit = (context, a) => {
  app = a
}

export const otherAction = (context) => {
  // use the event bus or whatever
  app.$root.$emit(...)
}

@shredmaster
Copy link

import App from './App.vue';

const myStore = new Vuex.Store({
    state: {
        ...
    },
    actions: {
        myAction(ctx, data) {
              // here you can use this.$app to access to your vue application
        }
    }
});

const app = new Vue({
    el: '#my-div',
    render: h => h(App),
    store: myStore
});

myStore.$app = app; // <--- !!! this line adds $app to your store object

it didn't work for me, mounting after assign the root instance did the trick.

const app = new Vue({
  router,
  store,
  render: h => h(App)
})
store.$app = app
app.$mount('#app') 

@gaby64
Copy link

gaby64 commented Dec 31, 2019

I found this._vm works

@comod
Copy link

comod commented Jan 15, 2020

Why not
import Vue from 'vue'
...
Vue.set(...)

... Works for me

@1isten
Copy link

1isten commented Mar 13, 2020

This works for me:

import Vue from 'vue';

// ...

export const actions = {
  yourAction() {
    console.log(Vue.prototype.$nuxt.$notify);
  },
};

See https://stackoverflow.com/a/58557693/10222165

@Dean-Christian-Armada
Copy link

Dean-Christian-Armada commented Mar 31, 2020

@1isten . You can simply use this on NuxtJS Vuex

@temple
Copy link

temple commented May 30, 2020

I found this._vm works

@gaby64 it cannot work because of this instruction, which is called unconditionally when you create an instance of Store

@gaby64
Copy link

gaby64 commented May 30, 2020

I found this._vm works

@gaby64 it cannot work because of this instruction, which is called unconditionally when you create an instance of Store

works to access Vue prototype objects

@henriquek3
Copy link

This works for me:

window.$_app = this

@hanzlahabib
Copy link

this._vm works for me

@michug
Copy link

michug commented Mar 10, 2022

this._vm no longer seems to work on vuex 4.0

@MJGTwo
Copy link

MJGTwo commented Apr 8, 2022

for those who are using Vuex@3.6.2 and are confused by this._vm not working: the this property is not defined in fat arrow functions (anonymous functions assigned to variables) due to not being a traditional function.

source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

an example invoking a bootstrap-vue toast component:

const store = new Vuex.Store({
  state: {
    foo: '',
  },
  mutations: {
    setFoo(state, {foo}){
      state.foo = foo;
    }
  },
  actions: {
    verifyFooWrong: ({commit}, {foo}) => {
      if (typeof foo !== 'string'){
         this._vm.$bvToast.toast(             // <--- `'this' is not defined`
           'foo must be of type string',
           {
             title: 'type error',
             autoHideDelay: 5000,
             variant: 'danger',
           }
         );
      }
      else {
        commit('setFoo',{foo});
      }
    },
    verifyFooRight({commit}, {foo}){
      if (typeof foo !== 'string'){
         this._vm.$bvToast.toast(
           'foo must be of type string',
           {
             title: 'type error',
             autoHideDelay: 5000,
             variant: 'danger',
           }
         );
      }
      else {
        commit('setFoo',{foo});
      }
    }
}

sorry if this doesn't run; i typed it out in this input field.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests