Vue3 Userouter

Posted on  by admin

My team is trying to do a proof of concept project with Vue 3. I was away, and when I came back, I was put onto a codebase that *worked*, absolutely, but it was basically a lift-and-shift from Vue2, with all the associated Vue 2 syntax (that is, no composition API). I'm trying to refactor into the composition API, to show the team the "new way" and why it's cleaner.

Programmatic Navigation

But I'm having a major problem with unit testing. In the prior code, Vue Router passed in a parameter value from the URL - that is, the path "/path/to/:hash" would provide this.$route.params.hash -- which would then be accessible via 'this.hash'.

Project Structure

To unit test this with the Vue 2 syntax, you could just provide 'hash' as a prop, and since both eventually got transformed to 'this.hash', it worked fine. But now, using useRoute() for vue router, that trick no longer works.

Which brings me to a conundrum - how the heck do you set a route parameter in unit tests?

Right now we're using Vue-Testing-Library, and none of the examples using vue router for Vue-Testing-Library incorporate any sort of ability for you to set route parameters (or queries, I noticed, but that's a different kettle of fish).

Any issues in github to this effect by the team are dismissed with: "If you want to set route paramaters, you should instead grab the link from the dom that gets you to the correct hash and then test from there," completely ignoring the case where their is no link, and the hash is generated on the backend.

(The hash in this case is for when someone wants to reset their password after they forgot it and they are given a unique link -- with hash -- in their email to do so).

Setup Vue 3 Project

I've googled my brains out looking for a solution. Figured I'd come here. I think @chris-zhu was originally aiming to access the router to perform actions such as pushing new URLs inside of Vuex.

  1. Do I understand from your explanation @cecitorres that this is impossible under Vuex4?
  1. That the only place where the router can really be reached is within the setUp() function of Vue components, which in turn means that anybody still using the Options API is out of luck and needs to upgrade?

If this is true, then it seems that the "answer" is a pretty lengthy bit of re-work to:.

Find all Vuex actions which contain this.$router under Vuex 3, and change them to accept a new router argument.

  • Find all Vue Components which call those actions and convert them into Composition API.
  • Use useRouter() in the setup() method of all of those Vue Components, and pass it into Vuex using the new parameter.
  • I completely agree that Composition API is the way forward, but it feels like this forcing an upgrade which I was hoping to popstpone until later.

Or is there any easier way? While the above set of steps should probably work, on reflection I've realised that having routing code in Vuex is a red flag from a separation of concerns perspective; Vuex should be about storing re-usable data and not handling routing. So my approach will be to move that logic out into normal Vue Components, where the original this.$router syntax will still work, which will allow me to continue using Options API short-term if I like.

In this tutorial, we’re gonna build Vue 3 Authentication & Authorization example with JWT, Vuex, Axios, Vue Router and VeeValidate.

I will show you:. JWT Authentication Flow for User Signup & User Login.

Project Structure for Vue 3 Authentication with Vuex 4 & Vue Router 4. How to define Vuex Authentication module.

Creating Vue 3 Authentication Components with Vuex Store.

Reactive Form Validation with VeeValidate 4. Vue 3 Components for accessing protected Resources. How to add a dynamic Navigation Bar to Vue 3 App. Let’s explore together.

Related Post: – In-depth Introduction to JWT-JSON Web Token – Vue 3 CRUD example with Axios & Vue Router.

Fullstack: – Spring Boot + Vue.js: Authentication with JWT & Spring Security Example – Node.js Express + Vue.js: JWT Authentication & Authorization example.

Create Services. Create Vue Authentication Components. Create Vue Components for accessing Resources. We will build a Vue 3 application in that:. There are Login/Logout, Signup pages. Form data will be validated by front-end before being sent to back-end.

Depending on User’s roles (admin, moderator, user), Navigation Bar changes its items automatically. – Form Validation could look like this:. – Login Page & Profile Page (for successful Login):.

– Navigation Bar for Admin account:. You will need to add Refresh Token, more details at:Vue 3 Refresh Token with Axios and JWT example.

This is full Vue JWT Authentication App demo (with form validation, check signup username/email duplicates, test authorization with 3 roles: Admin, Moderator, User).

In the video, we use Spring Boot for back-end REST APIs. In the video, we use Vue 2 and VeeValidate 2, but logic and UI are the same as this tutorial. For JWT Authentication, we’re gonna call 2 endpoints:. POST api/auth/signup for User Registration.

POST api/auth/signin for User Login.

You can take a look at following flow to have an overview of Requests and Responses Vue Client will make or receive.

Vue Client must add a JWT to HTTP Authorization Header before sending request to protected resources. You can find step by step to implement these back-end servers in following tutorial:.

Lazy loading

Now look at the diagram below. Let’s think about it. – The App component is a container with Router. It gets app state from Vuex store/auth. Then the navbar now can display based on the state.

App component also passes state to its child components.

– Login & Register components have form for submission data (with support of vee-validate).

We call Vuex store dispatch() function to make login/register actions. – Our Vuex actions call auth.service methods which use axios to make HTTP requests.

Where to go from here

We also store or get JWT from Browser Local Storage inside these methods. – Home component is public for all visitor. – Profile component get user data from its parent component and display user information.

– BoardUser, BoardModerator, BoardAdmin components will be displayed by Vuex state user.roles.

In these components, we use user.service to get protected resources from API. – user.service uses auth-header() helper function to add JWT to HTTP Authorization header. auth-header() returns an object containing the JWT of the currently logged in user from Local Storage.

Add Navigation Bar to Vue App

We will use these modules:. vue-fontawesome 3. This is folders & files structure for our Vue 3 Authentication & Authorization with JWT application:. With the explanation in diagram above, you can understand the project structure easily.

Open cmd at the folder you want to save Project folder, run command:vue create vue-3-authentication-jwt.

You will see some options, choose Default ([Vue 3] babel, eslint).

After the project is ready, run following command to install neccessary modules:.

After the installation is done, you can check dependencies in package.json file.

In src folder, we create plugins/font-awesome.js file with following code:.

Open src/main.js, modify code inside as below:.

You can see that we import and apply: – store for Vuex (implemented later in src/store) – router for Vue Router (implemented later in src/router.js) – bootstrap with CSS – vue-fontawesome for icons (used later in nav).

We create two services in src/services folder:.

auth-header.js. auth.service.js (Authentication service).

user.service.js (Data service).

The service provides three important methods with the help of axios for HTTP requests & reponses:.

login(): POST {username, password} & save JWT to Local Storage.

How to use router params with Vue Router

logout(): remove JWT from Local Storage. register(): POST {username, email, password}. For more details about ways to use Axios, please visit:Axios request: Get/Post/Put/Delete example. We also have methods for retrieving data from server. In the case we access protected resources, the HTTP request needs Authorization header.

Let’s create a helper function called authHeader() inside auth-header.js:.

It checks Local Storage for user item.

If there is a logged in user with accessToken (JWT), return HTTP Authorization header.

Otherwise, return an empty object. Note: For Node.js Express back-end, please use x-access-token header like this:. Now we define a service for accessing data in user.service.js:. You can see that we add a HTTP header with the help of authHeader() function when requesting authorized resource. We put Vuex module for authentication in src/store folder.

auth.module.js (authentication module).

index.js (Vuex Store that contains all modules). Now open index.js file, import auth.module to main Vuex Store here.

Conclusion

Then we start to define Vuex Authentication module that contains:. state: { status, user }. actions: { login, logout, register }. mutations: { loginSuccess, loginFailure, logout, registerSuccess, registerFailure }.

We use AuthService which is defined above to make authentication requests. You can find more details about Vuex at Vuex Guide. Let’s continue with Authentication Components. Instead of using axios or AuthService directly, these Components should work with Vuex Store: – getting status with this.$store.state.auth – making request by dispatching an action: this.$store.dispatch().