Compile error when trying to access a getter function in Veux 4 store of Quasar V2 beta app - vue.js

Compile error when trying to access a getter function in Veux 4 store of Quasar V2 beta app.
Unsafe member access ['item/getRandomNumber'] on an any value.eslint#typescript-eslint/no-unsafe-member-access
Error not going even after disabling it.
Please explain the cause the error and how to sort it out.
setup() {
return { randomNumber: computed(() => store.getters['item/getRandomNumber']) }
},
getter.ts under module item
import { GetterTree } from 'vuex';
import { StateInterface } from '../index';
import { ItemStateInterface } from './state';
const getters: GetterTree<ItemStateInterface, StateInterface> = {
getRandomNumber ( /* context */) {
return 20;
}
};
export default getters;
index.ts under module item
import { Module } from 'vuex';
import { StateInterface } from '../index';
import state, { ItemStateInterface } from './state';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const itemModule: Module<ItemStateInterface, StateInterface> = {
namespaced: true,
actions,
getters,
mutations,
state
};
export default itemModule;
store/index.ts
import { store } from 'quasar/wrappers'
import { InjectionKey } from 'vue'
import {
createStore,
Store as VuexStore,
useStore as vuexUseStore,
} from 'vuex'
import item from './module-item'
import { ItemStateInterface } from './module-item/state';
export interface StateInterface {
item : ItemStateInterface
}
declare module '#vue/runtime-core' {
interface ComponentCustomProperties {
$store: VuexStore<StateInterface>
}
}
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')
export default store(function (/* { ssrContext } */) {
const Store = createStore<StateInterface>({
modules: {
item
},
// enable strict mode (adds overhead!)
// for dev mode and --debug builds only
strict: !!process.env.DEBUGGING
})
return Store;
})
export function useStore() {
return vuexUseStore(storeKey)
}

Related

Vue3 Pinia Store cannot access 'store" before initializsation

I have a UserStore which contains some information about the current user. This store also is responsible for loggin in and out.
In order to make the getters available I map the getters to my computed attribute within my Vue component.
Unfortunately I get an error saying that it cannot access useUserStore before initilization.
This is my component:
<template>
//...
</template>
<script>
import {mapState} from "pinia"
import {useUserStore} from "../../stores/UserStore.js";
import LoginForm from "../../components/forms/LoginForm.vue";
export default {
name: "Login",
components: {LoginForm},
computed: {
...mapState(useUserStore, ["user", "isAuthenticated"]) //commenting this out makes it work
}
}
</script>
This is my store:
import { defineStore } from 'pinia'
import {gameApi} from "../plugins/gameApi.js"
import {router} from "../router.js";
export const useUserStore = defineStore("UserStore", {
persist: true,
state: () => ({
authenticated: false,
_user: null
}),
getters: {
user: (state) => state._user,
isAuthenticated: (state) => state.authenticated
},
actions: {
async checkLoginState() {
// ...
},
async loginUser(fields) {
// ...
},
async logutUser() {
// ...
}
}
})
And my main.js
import {createApp} from 'vue'
import App from './App.vue'
import gameApi from './plugins/gameApi'
import {router} from './router.js'
import store from "./stores/index.js";
createApp(App)
.use(store)
.use(router)
.use(gameApi)
.mount('#app')
And finally my store configuration:
import {createPinia} from "pinia"
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import {useUserStore} from "./UserStore.js";
const piniaStore = createPinia()
piniaStore.use(piniaPluginPersistedstate)
export default {
install: (app, options) => {
app.use(piniaStore)
const userStore = useUserStore()
const gameStore = useGameStore()
}
}
I wasn't able to initialize the store using the "old" way comparable with Vuex. Instead I had to make use of the setup() function Pinia Docu:
<script>
import {useUserStore} from "../../stores/UserStore.js";
export default {
name: "RegisterForm",
setup() {
// initialize the store
const userStore = useUserStore()
return {userStore}
},
data() {
return {
// ...
}
},
methods: {
checkLoginState() {
this.userStore.checkLoginState()
}
}
}
</script>

Vue3 - Persisting state with Page refresh

I have just started using Vue3, and am trying to use vuex to manage state. when using Vue2 I would call the store each time the app loads like this:
// mains.js
import VueRouter from "vue-router";
import Vuex from "vuex";
import router from "./routes";
window.Vue = require('vue').default;
Vue.use(VueRouter);
Vue.use(VueMoment);
Vue.use(Vuex);
const store = new Vuex.Store(storeDefinition);
const app = new Vue({
el: '#app',
router,
store,
components: {
"index": Index
},
async created() {
this.$store.dispatch("loadStoredState");
this.$store.dispatch("loadUser");
},
});
This is my vuex store that defines state, mutations and actions for vuex:
// store.js
import { isLoggedIn, logOut } from "./shared/utils/auth";
export default {
state: {
isLoggedIn: false,
user: {}
},
mutations: {
setUser(state, payload) {
state.user = payload;
},
setLoggedIn(state, payload) {
state.isLoggedIn = payload;
}
},
actions: {
loadStoredState(context) {
context.commit("setLoggedIn", isLoggedIn());
},
async loadUser({ commit, dispatch }) {
if (isLoggedIn()) {
try {
const user = (await axios.get("/user")).data;
commit("setUser", user);
commit("setLoggedIn", true);
} catch (error) {
dispatch("logout");
}
}
},
logout({ commit }) {
commit("setUser", {});
commit("setLoggedIn", false);
logOut();
}
},
getters: {}
}
This file manages a cookie for local storage that stores a boolean value for isLoggedIn:
// auth.js
export function isLoggedIn() {
return localStorage.getItem("isLoggedIn") == 'true';
}
export function logIn() {
localStorage.setItem("isLoggedIn", true);
}
export function logOut() {
localStorage.setItem("isLoggedIn", false);
}
But in Vue3 I am creating the main.js file like this:
// mains.js
const { createApp } = require('vue')
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from "./store";
const store = createStore(storeDefinition)
createApp(Index)
.use(createRouter())
.use(store)
.mount('#app')
How can I add the two calls to manage the store to the createApp function?
You can add the created hook to the root component by using the extends option with the component definition:
// main.js
import { createApp } from 'vue'
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from './store'
const store = createStore(storeDefinition)
createApp({
extends: Index,
created() {
this.$store.dispatch('loadStoredState')
this.$store.dispatch('loadUser')
},
})
.use(createRouter())
.use(store)
.mount('#app')
demo

Access app.config.globalProperties in vuex store

I got a vuex store like this:
const state = {
status: '',
};
const getters = {
//...
};
const actions = {
// ...
};
const mutations = {
// ...
};
export default {
namespaced: true,
state,
getters,
actions,
mutations,
}
Now I'd like to access app.config.globalProperties.$notify
In Vue.js2 I was using something like Vue.prototype.$notify, but this is not working anymore.
$notify is also provided like this:
app.use(routes)
.provide('notify', app.config.globalProperties.$notify)
.mount('#app')
Unfortunately I did not find any information about this in the docs yet.
So my question: How can I either inject $notify or access app.config.globalProperties within this store?
From your store and its modules, you could return a store factory -- a function that receives the application instance from createApp and returns a store:
// store/modules/my-module.js
const createStore = app => {
const mutations = {
test (state, { committedItem }) {
app.config.globalProperties.$notify('commited item: ' + committedItem)
}
}
return {
namespaced: true,
//...
mutations,
}
}
export default app => createStore(app)
// store/index.js
import { createStore } from 'vuex'
import myModule from './modules/my-module'
export default app =>
createStore({
modules: {
myModule: myModule(app)
}
})
Then use the store factory like this:
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import createStore from './store'
const app = createApp(App)
app.use(createStore(app)).mount('#app')
demo

How do I access my state object in store from module?

I need a data from my store object above in my module, but I cannot access it.
I have a store object
This store object has one or more modules it uses.
I was try it :index.js
import { createStore } from "vuex";
import moduleLayout from "./modules/moduleLayout.js"
export default createStore({
state:{
testData:'Hello World!'
},
modules: { moduleLayout }
})
and have a moduleLayout.js
export default {
state:{
size:100
},
getters:{
getSizeAndText:(state)=>{
return {size:state.size,text:this.state.testData};
//error here, because (this)undefined
//how can i access on here testData
}
}
}
I cannot access testData data from my moduleLayout.js
No need to import index.js.
We can access it by expanding the parameter field.
on "index.js"
import moduleTest from "./modules/moduleTest";
export default{
state:{
size:100
},
modules:{
moduleTest:moduleTest
}
}
on "moduleTest.js"
export default{
state:{
testSize:20
},
getters: {
getSumSize(thisState, getters, state) {
return thisState.testSize+state.size;//this result 120
},
getSumSizeWithParam:(thisState, getters, state) =>(index)=>{
return (thisState.testSize+state.size)*index;//this result 120*index
}
}
}
You definitely don't need to import index.js.
You are not adding the module to the store.
import { createStore } from "vuex";
import moduleLayout from "./modules/moduleLayout.js";
export default createStore({
state: {
testData: 'Hello World!'
},
modules: {
layout: moduleLayout
}
})
Import the store inside module to access the state thats not namespaced by module:
import store from '../index.js'; // whatever the path of where you create and export store
const state = {
size: 100
}
const getters = {
getSizeAndText(state) {
return {
size: state.size,
text: store.state.testData
}
}
}
export default {
state,
getters
}

Unable to use Vuex Store in Nuxt layouts

I am trying to use Vuex Store in my layout but can't figure out how to make it work.
Here is what I am doing:
store/sources.ts
import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'
import { store } from '#/store'
import axios from 'axios'
const { sourcesEndpoint } = process.env
interface Source {
id: String
}
#Module({
name: 'sources',
namespaced: true,
stateFactory: true,
dynamic: true,
store,
})
export default class Sources extends VuexModule {
private _sources: Source[] = []
get sources(): Source[] {
return this._sources
}
#Mutation
updateSources(sources: Source[]) {
this._sources = sources
}
#Action({ commit: 'updateSources' })
async fetchSources() {
// eslint-disable-next-line no-console
console.log(`!!! ${sourcesEndpoint} !!!`)
return sourcesEndpoint ? await axios.get(sourcesEndpoint) : []
}
}
store/index.ts
import { Store } from 'vuex'
export const store = new Store({})
layouts/default.vue
<script>
import { getModule } from 'vuex-module-decorators'
import Sources from '#/store/sources'
export default {
fetch() {
const sourcesModule = getModule(Sources, this.$store)
sourcesModule.fetchSources()
},
fetchOnServer: false,
}
</script>
And the error I get:
[vuex] must call Vue.use(Vuex) before creating a store instance.
You need to add Vue.use(Vuex), also, you are not including your module in the main store
import { Store } from 'vuex'
import { Sources } from './sources'
Vue.use(Vuex)
export const store = new Store({
modules: {
Sources
}
})