Как получить доступ к экземпляру vue в Vuex

#vue.js #vuex

Вопрос:

Я объявляю глобальную переменную в main.js Vue.js проект.

 Vue.prototype.$API = "myapihere"
 

И я хочу использовать это отовсюду.
и это правильно работает при использовании this.$API .

Но в Vuex это не работает.

 console.log(this.$API);
 

Здесь this.$API не определено.

Как я использую свой $API in Vuex.

Комментарии:

1. this в vuex не ссылается на экземпляр vue, поэтому он не работает, попробуйте this._vm .

2. Это не работает, если у вас есть действия, средства получения и т.д. В отдельных файлах.

3. @VinceKronlein на этот вопрос уже дан ответ.

4. Да, но это неверно. Когда действия, мутации и т.д. Импортируются из файлов, к которым у этих файлов нет доступа this._vm , в моем actions.js файле this не определено.

5. @VinceKronlein, может быть… Я не уверен, я писал отдельный файл для одного логического компонента, в этот файл я включаю все (действия, состояние, мутации и т. Д.) Этого компонента.

Ответ №1:

Ответ Vue 2 и Vuex 3

В магазине вы можете получить доступ к экземпляру vue, обратившись this._vm

 const store = new Vuex.Store({
  mutations: {
    test(state) {
      console.log(this._vm);
    }
  }
});
 

Комментарии:

1. Обратите внимание, что это не работает в Vuex 4 (Vuex совместим с Vue 3). Даже в Vuex 3 он не был частью общедоступного API. Использование недокументированных функций/свойств-это рецепт возникновения проблем в будущем…

Ответ №2:

Я использую Vue 3 и Vue.prototype.$foo , похоже, был удален для этой версии. Я также обнаружил, что в моей версии VueX этого нет this._vm .

Я изучил метод предоставления / введения, который рекомендуется в документах Vue 3. Это хорошо работало для доступа к глобалам из моих компонентов, но я не мог получить к ним доступ из магазина.

Решение , которое я выбрал, состояло в том, чтобы использовать свойства globalProperties для объекта Vue и стандартные свойства store и установить их непосредственно перед установкой приложения.

main.js :

 import store from './store/index';
import App from './App.vue';

// Load custom globals
import conf from '@/inc/myapp.config';

const app = createApp(App)
  .use(store);

// Register globals in app and store
app.config.globalProperties.$conf = conf;
store.$conf = conf;

app.mount('#app');
 

Что мне в этом нравится, так это то, что я могу одинаково обращаться к глобалам как в магазине, так и в компонентах.

В компоненте:

 export default {
  data() {
    return {
    };
  },
  created() {
    console.log( this.$conf.API_URL );
  },
}
 

…и вы можете получить доступ this.$conf.API_URL таким же образом из действий, мутаций и геттеров.

Как только я нашел это решение, мне больше не требовался доступ ко всему экземпляру Vue из магазина, но если вам это нужно по какой-то причине, вы можете назначить store.$app = app ; в том же месте main.js .

Комментарии:

1. Я не вижу никаких упоминаний об globalProperties этом в документах Vue 2 , так что вам придется немного почитать об этом и поэкспериментировать, но я полагаю, что принцип все еще остается в силе. Мне было бы любопытно узнать, как у вас дела.

2. Работает только в js, вы не можете сделать это в машинописном виде

Ответ №3:

У вас есть 2 подхода:

  1. Передайте свойство (или даже получите доступ к _vm свойству изнутри Vuex) в качестве аргумента компонента
     methods: {
      this.$store.dispatch('someAction', this.$API)
    }
     
  2. Объявите и экспортируйте ту же переменную из другого файла и используйте ее из своего main.js И ваш файл Vuex:
     // api.js
    export const API = "http://localhost:5000/api"
     
     // main.js
    import { API } from './api.js
    ...
    Vue.prototype.$API = API
     
     // store.js
    import { API } from './api.js
    
    // you can use API now!
     

Хотя я лично склонялся бы ко второму, я бы вообще не стал хранить путь API в Vue, так как я бы предпочел api.js , чтобы файл был службой для выполнения всех вызовов ajax и использования этого файла там, где мне нужно.

Ответ №4:

использовать this._vm

вот почему

по умолчанию, когда вы заходите this в vuex store него, он будет указывать store , поэтому он будет выводить что-то вроде этого

введите описание изображения здесь

итак, после этого вы видите, что в магазине есть что-то, что называется _vm , вот оно введите описание изображения здесь

таким образом, это _vm указывает на компонент vue, поэтому для доступа к нему вам нужно будет использовать this._vue

вы можете лучше создать средство получения экземпляра vue, например

 const store = new Vuex.Store({
  getters: {
    vue(state) {
      return this._vm
    }
  }
});

//so you can use it across your store
store.getters.vue

//Note
//the above way of accessing getter works on non `namespaced` stores