question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Guidance for integration of Typescript and Vuex 4 / Pinia 2

See original GitHub issue

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I’m always frustrated when […]

I’m needing some guidance on how to use Typescript with Vuex v4 and Quasar 2. Vuex v4 recommends registering Typescript typed Vuex stores using this code …

However Quasar 2 appears to registers the root store for you and unlike Quasar 1.x there’s no main.ts or main.js anymore to apply app.use() before the app is mounted. I suspect that registering in a boot file is too late as the root store has already been created for you.

// main.ts
import { createApp } from 'vue'
import { store, key } from './store'

const app = createApp({ ... })

// pass the injection key
app.use(store, key)  // <<< Probably too late to do this in a boot script.  Unclear if this is required *per store* or root store only??

app.mount('#app')

Describe the solution you’d like A clear and concise description of what you want to happen.

Perhaps an update on the Quasar 2.x Vuex page with advice for Vuex 4 and Typescript.

Describe alternatives you’ve considered A clear and concise description of any alternative solutions or features you’ve considered.

I also tried to use pinia with a boot script but hit other issues with Quasar 2. The pinia v2 stores lost my getters and actions for some reason - possibly related to conflicts with existing vuex store registration done by Quasar??. I ended up tossing the pinia stores and trying Vuex 4 only to hit another problem. I noted pinia had special instructions for Nuxt so probably Quasar needs some custom code to work with pinia v2 perhaps done in collaboration with the pinia team.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

27reactions
nicojmbcommented, Nov 12, 2021

Hi, i successfuly integrated pinia in quasar 2!!!

in quasar.conf.js add pinia boot file

boot: [
      'i18n',
      'pinia'  // add this
    ],

in /src/boot, create a pinia.ts

import { boot } from 'quasar/wrappers'
import { createPinia } from 'pinia'

export default boot(({ app }) => {
  app.use(createPinia())
})

create a store file: /src/stores/user.ts

import { defineStore } from 'pinia'

const storeID = 'user'

interface IUser {
  loggedIn: boolean,
}

const User: IUser = {
  loggedIn: false
}

export { IUser }

export const useUserStore = defineStore({

  id: storeID,

  state: (): IUser => JSON.parse(localStorage.getItem(storeID) ?? JSON.stringify(User)) as IUser,

  actions: {
    login (username: string, password: string, remember = true): boolean {
      if (username === 'admin' && password === 'admin') {
        this.loggedIn = true
      }

      return this.loggedIn
    },
    logout (): boolean {
      this.loggedIn = false
      return true
    }
  },
  getters: {
    isLoggedIn (): boolean {
      return this.loggedIn
    }
  }
})

export type UserStore = ReturnType<typeof useUserStore>

use the store in any vue component/page/layout:

<template>
Is logged in: {{ isLoggedIn  }}
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
import { useQuasar } from 'quasar'
import { useUserStore } from 'src/stores/user'

export default defineComponent({
  name: 'Login',
  setup () {

    const userStore = useUserStore()

    
    // example call a action
    userStore.login(form.username, form.password);

   // example call a getter
   const  isLoggedIn = user.isLoggedIn; ​

   ​return { 
      ​isLoggedIn 
   ​}
 ​}
})
</script>

and you can also use in routes to protect with router guards, example /src/router/index.ts

import { route } from 'quasar/wrappers'
import {
  createMemoryHistory,
  createRouter,
  createWebHashHistory,
  createWebHistory
} from 'vue-router'
import routes from './routes'
import { useUserStore } from 'src/stores/user'
/*
 * If not building with SSR mode, you can
 * directly export the Router instantiation;
 *
 * The function below can be async too; either use
 * async/await or return a Promise which resolves
 * with the Router instance.
 */

export default route(function (/* { store, ssrContext } */) {
  const createHistory = process.env.SERVER
    ? createMemoryHistory
    : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory)

  const Router = createRouter({
    scrollBehavior: () => ({ left: 0, top: 0 }),
    routes,

    // Leave this as is and make changes in quasar.conf.js instead!
    // quasar.conf.js -> build -> vueRouterMode
    // quasar.conf.js -> build -> publicPath
    history: createHistory(
      process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE
    )
  })

  Router.beforeEach((to, from, next) => {
    if (to.matched.some(route => route.meta.requiresAuth)) {
      const user = useUserStore()

      if (!user.isLoggedIn) {
        next({ name: 'Login' })
      } else {
        next()
      }
    } else {
      next()
    }
  })

  return Router
})

and /src/router/routes.ts

import { RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    component: () => import('layouts/MainLayout.vue'),
    children: [{ path: '', name: 'Dashboard', component: () => import('src/pages/Dashboard.vue') }],
    meta: {
      requiresAuth: true
    }
  },
  {
    path: '/auth',
    component: () => import('layouts/AuthLayout.vue'),
    children: [{ path: 'login', name: 'Login', component: () => import('pages/auth/Login.vue') }]
  },
  {
    path: '/:catchAll(.*)*',
    component: () => import('pages/errors/404.vue')
  }
]

export default routes
0reactions
yusufkandemircommented, Apr 5, 2022

First-party Pinia support is released in @quasar/app-vite-v1.0.0-beta.1 and @quasar/app-webpack-v3.4.0. It’s been available for almost a month now, so I am closing this issue. Thanks for the feature request!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Introduction - Pinia
Since then, the initial principles have remained the same, but Pinia works for both Vue 2 and Vue 3 and doesn't require you...
Read more >
Pinia vs. Vuex: Which state management library is best for Vue?
Compare documentation, learning curves, and use cases for the Pinia and Vuex state management libraries for your next Vue.js project.
Read more >
Advantages of Pinia vs Vuex - Vue Mastery
1. Pinia has a Simpler API than Vuex · 2. Pinia is modular by design · 3. Pinia comes with Devtools · 4....
Read more >
Use Composition API and Pinia in Vue 2 Project
Vue 3 also introduces Pinia as the recommended state management library, superceding Vuex that now enters maintenance mode. It would be nice if ......
Read more >
Vuex 4 TypeScript Tutorial // Learn Vuex 4 + Vue 3 ... - YouTube
Vuex 4 with Vue.js 3 and TypeScript is a great combination. In this video we'll explore how to ... 25K views 2 years...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found