0

Let's say I want to make a utility function that redirects users to a route if they aren't authenticated.

This function resides in a utils.js file; it isn't declared in any one component.

// utils.js
export function redirectIfNotAuthenticated (app, path) {
  if (!app.$store.state.isAuthenticated) {
    app.$router.push(path)
  }
}

this function is then imported into single-file components and called like: redirectIfNotAuthenticated(this, '/login').

I think having an app parameter and having to explicitly pass this from the component is ugly. Is there a better way to have a stateless helper function access the scope of the calling component in vue? As in, is there a way to bind functions that don't live inside of a .vue file to the calling instance of the vue app?

2 Answers 2

1

To handle redirection, instead of putting logic inside component, you can use vue-router's navigation guards to handle on top level instead:

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  if (!isAuthenticationRequired(to)) { // your logic to ignore authentication for custom routes, e.g. login 
    next();
  } else if (!isAuthenticated()) { // your logic which needs access to Vuex's store
    next('login');
  } else {
    next();
  }
})

Then, if you create a store object and add it to your Vue app instance, like in the default example of Vuex , you can refer to the object directly without any need to access the Vue app, since same store object is used:

// utils.js
import store from '../your_path/your_file.js';

export function isAuthenticated() {
  return store.state.isAuthenticated;
}
Sign up to request clarification or add additional context in comments.

2 Comments

+1. From a business logic, separation-of-concern standpoint, where would be the best place to define functions like isAuthenticationRequired in my project?
@SamueleB. Since the function take to as input, and likely nothing else from anything other parts (e.g. store, views, etc.), it can be a helper function for your router logic. Personally I would create a file named utils/routingUtils.js to put it inside, but it's more of personal taste.
0

The best practice in this situation is to use router navigation guards :

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
   next(vm=>!vm.$store.state.isAuthenticated)
//vm refers to the vue instance
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.