Skip to content
New issue

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

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

Already on GitHub? Sign in 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()

@flowck
Copy link

flowck commented Sep 13, 2018

@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.

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

No branches or pull requests