store does'nt persist pinia vuejs - vue.js

i work on vuejs version 2.9 and i want to persist my store when the page is refreshed.
i use pinia and make like the online documentation : https://prazdevs.github.io/pinia-plugin-persistedstate/guide/
main.ts :
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
const app = createApp(App);
app.use(createPinia());
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate);
app.use(router);
app.mount("#app");
my store :
import { defineStore } from "pinia";
export const TokenStore = defineStore({
id: "token",
state: () => ({
email:"",
pseudo: "",
myid: "",
nom:"",
prenom:"",
role: "",
token:"",
avatar:"",
}),
persist: true,
});
An idea for the reason of it doesn't work ? Or an other way to persist my store ?

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>

how to use pinia store in a vue router navigation guard?

I'm using Vuejs 3, vuerouter 4 and pinia and trying to put a navigation guard in some routes, as per the example in the documentation (if a user is not authenticated and is not on the login page, send the user to login page to get authenticated). This is explained also in pinia documentation on use of pinia outside of components. But I can't get my head around it.
The store I use is currently simple (return false or true on isAuthenticated):
//authStore.js
import { defineStore } from "pinia";
export const useAuthStore = defineStore( 'AuthStore', {
state: () => {
return {
isAuthenticated: false
}
}
})
I want to use this isAuthenticated in a beforeEnter in routes/index.js
In main.js:
import { useAuthStore } from '#/stores/authStore'
import { createApp } from 'vue'
import App from './App.vue'
import router from '#/router'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia()).use(router)
app.mount('#app')
// I'm not using authStore in this file, so this raises an error:
const authStore = useAuthStore()
And in router/index.js:
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
// path for login page,
{
path: '/adm/home',
name: 'AdmView',
component: () => import('#/views/adm/AdmView.vue'),
beforeEnter: (to) => {
// error: authStore is not defined
const isAuthenticated = authStore
if ( !isAuthenticated && to.name !== 'login-adm' ) {
return { name: 'login-adm' }
}
}
},
// other paths
]
Your authStore.js exports useAuthStore as expected, but you do not call it as required.
authStore is not defined because authStore is the filename of your auth store -- instead you should be executing the function useAuthStore exported from that file:
const authStore = useAuthStore();
console.log('Is authenticated?', authStore.isAuthenticated);
I don't know if it is the main issue but u forgot to use a destructor on userStore doing
const isAuthenticated = authStore
It supposed to be
const { isAuthenticated } = toRefs(authStore);
toRefs to preserve reactivity after passing. It can be imported as
import { toRefs } from 'vue';

I need change vue resources to axios

I'm creating an application based on this code from github.
I need change vue resources to axios, how i can do that ?
I would like to know how to do this keeping the structure of this code.
I'm using vue 3.
Anyone who can help would be very grateful :)
the full code i'm modifying: here
http:
import Vue from 'vue'
import VueResource from 'vue-resource'
import services from './services'
Vue.use(VueResource)
const http = Vue.http
http.options.root = 'https://localhost.com/api'
Object.keys(services).map(service =>{
services[service] = Vue.resource('', {}, services[service])
})
export { http }
export default services
http services:
import { services as auth } from '#/modules/auth'
export default {
auth
}
Actions:
import services from '#/http'
import * as types from './mutation-types'
export const ActionDoLogin = (context, payload) =>{
return services.auth.login(payload)
}
export const ActionSetUser = ({ commit }, payload) => {
commit(types.SET_USER, payload)
}
export const ActionSeToken = ({ commit }, payload) => {
commit(types.SET_TOKEN, payload)
}
Services:
export default {
login: { method: 'post', url: 'login' }
}
Main:
import { createApp } from 'vue'
import App from './App'
import router from './router'
import store from './store'
import './assets/scss/app.scss'
createApp(App).use(store).use(router).mount('#app')
Login view:
<script>
import {mapActions} from 'vuex'
export default {
data: () =>({
form:{
email:'',
pass:''
}
}),
methods:{
...mapActions('auth', ['ActionDoLogin']),
submit(){
this.ActionDoLogin(this.form).then(res =>{
console.log(res.data)
})
}
}
}
</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

Why Vue doesn't see vuex?

I work with microfrontend single-spa (https://single-spa.js.org/)
I create a store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
}
})
in src/main.js i import it
import Vue from 'vue';
import singleSpaVue from 'single-spa-vue';
import 'devextreme/dist/css/dx.light.css';
import App from './App.vue';
import store from './store';
console.log("🚀 ~ file: main.js ~ line 6 ~ store", store)
Vue.config.productionTip = false;
Vue.prototype.$bus = new Vue();
const vueLifecycles = singleSpaVue({
store,
Vue,
appOptions: {
render(h) {
return h(App, {
store,
props: {
},
});
},
},
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
in console.log store displayed, but in the app cnsole.log(this) does not contain store
I don't understand where I am connecting wrong?
According to the docs, store should be a subproperty of appOptions:
const vueLifecycles = singleSpaVue({
// store, ❌
Vue,
appOptions: {
store, ✅
render(h) {
return h(App, {
// store, ❌
props: {},
})
},
},
})