Global pinia store accessible in every component - vue.js

I want to have my pinia "mainStore" to be accessible in whole app using this.store
i dont want to import in every component like this
import {store} from "#/stores/mainStore";
How can I do it?

Related

Initialize Pinia inside Vue 2 component

Is it possible to initialize Pinia store inside Vue 2 single file component? Right now I'm trying do this:
import { createPinia, PiniaVuePlugin } from 'pinia';
import Vue from 'vue';
Vue.use(PiniaVuePlugin);
const pinia = createPinia();
Vue.prototype.$pinia = pinia;
and it works in app but when I import this component to another App I'm having this error:
getActivePinia was called with no active Pinia. Did you forget to install pinia?
Is it even possible to initialize the pinia after main instance of app is created?

Transition from gobal Vue instance to app breaks import dependency

I'm looking at migrating a Vue 2 app to Vue 3 and ran into a problem. The Vue 2 app used to start with importing a whole lot of components and directives:
// these components register to the global Vue instance
import {ComponentA} from './componenta';
import {directiveA} from './directivea';
// create app (after the components are registered)
new Vue({...})
This worked fine, but when changing this code to Vue3, the app instance is now created instead. This instance isn't actually available when the global directives and components are imported.
What's the recommended way for dealing with this? I can't reorder the imports to the bottom of the file as webpack bundles them always at the top...
The order of imports does not matter in your case - what matters is the order of the JavaScript statements that follow the import section.
You should first create the app instance and only then register your global components to this instance - as explained in https://learnvue.co/2020/08/how-to-register-a-vue3-global-component/
import { createApp } from 'vue'
import PopupWindow from './components/PopupWindow'
import App from "./App.vue"
const app = createApp(App)
app.component('PopupWindow', PopupWindow) // global registration - can be used anywhere
app.mount('#app')
I settled with a solution that imports the app instance before component registration/definition (which occur within the component file) in an attempt to keep the current structure.
import {app} from './instance';
import './components/popupwindow';
import App from './app.vue';
const app = createApp(App)
app.mount('#app')
// instance.js
import {createApp} from 'vue';
const app = createApp();
export {app};
// popupwindow.vue
import {app} from '../instance';
// component registration+definition here (for global components only)
app.component('popup', {
...
}

State management in vue3 with vuex4 fails - Code shared in codesandbox

Dear friends of the modern lightweight web, I hope you can help a noobie regarding vue3 and Vuex 4.
I share timetable details (array of objects/dictionary) between multiple child components, which then can be displayed (e.g. Top 5 work) or edited (e.g. add new work details) in a way that these changes get reflected in all the other components. For this, I tried to use Vuex 4.
I am not able to access the state in a component. For debugging reasons, I even added a dummy entry during the creation of the state.
https://codesandbox.io/s/dazzling-brahmagupta-5sn1t?file=/src/main.js
Your demo uses Vuex 3 (perhaps that was a mistake only in the demo). Be sure to install Vuex 4, which provides the createStore() method:
npm i -S vuex#4
Also, the result of createStore() should be passed to app.use(), which is an instance method of the app from createApp() (not the App.vue component):
import { createApp } from 'vue'
import { createStore } from 'vuex'
import App from './App.vue'
const store = createStore(/*...*/)
// App.use(store) ❌ don't do this
createApp(App)
.use(store) ✅
.mount('#app')
demo

How to include a library to be available in whole Vue.js 3 project?

According to this blog post the correct way of including frequently used libraries (e.g. axios) in Vue.js 2 is to set them as property of Vue prototype object like this:
import axios from 'axios';
Object.defineProperty(Vue.prototype, '$axios', { value: axios });
Unfortunately, this approach is not working in Vue.js 3 anymore. So what is the correct way of importing library to be accesible in whole project? I would prefer not to set them as global variable (i.e. to the window object.)
To use provide/inject as an alternative
import { createApp } from 'vue'
import App from './App.vue'
import axios from 'axios';
const app = createApp(App)
app.provide('axios', axios ) // <-- define here
app.mount('#app')
Then in any component you wanna use axios you would do this
app.component('todo-list-statistics', {
inject: ['axios'],
created() {
this.axios // --> Injected property
}
}
I think the best way to us a library in a vue 3 project is to use the depency injection
https://v3.vuejs.org/guide/component-provide-inject.html
however I simply recommend that you import the library where you really need it, to have a more accurate intellisense, and a better three-shaking

Vue is not defined in components

I have file: components.js:
import Vue from 'vue'
import SelectCategory from './components/SelectCategoryComponent'
import CommentsManager from './components/CommentsManagerComponent'
Vue.component('select-category', SelectCategory);
Vue.component('comments-manager', CommentsManager);
In app.js I imported this file:
window.Vue = require('vue');
import './components'
But when page is loading I get error: Vue is not defined. When I add import Vue from 'vue' in every component then all working good. But how I can add Vue globally, without add import Vue from 'vue' in every component?
But how I can add Vue globally, without add import Vue from 'vue' in every component
You should not use global variables. Put import Vue from 'vue' in every file.
Now, if you still want to, use global instead of window. And make sure that file is loaded first. Or, you might want to set window= in your html file, and leave it out of every file.
As I can see within your components.js you have imported Vue and you have imported another Vue and you have put it to window object. so you have imported 2 different Vue within your application, as well there is no need to use components.js and app.js that can be confused later. so I suggest you put all your requirement within app.js file.
so app.js file will be like this :
import Vue from 'vue'; // es6 syntax
window.Vue = Vue;
import SelectCategory from './components/SelectCategoryComponent'
import CommentsManager from './components/CommentsManagerComponent'
Vue.component('select-category', SelectCategory);
Vue.component('comments-manager', CommentsManager);