My index route is defined as:
{ path: '/', adminOnly: false, component: Main },
Is there a way to access the 'adminOnly' property?
There seems to be no way of doing so in this block of code:
routes.beforeEach((to, from, next) => {
console.log(to)
next();
});
My routes file:
import Vue from 'vue';
import VueRouter from 'vue-router';
import Main from '../components/Main.vue';
import About from '../components/About.vue';
const NotFoundException = {
template: '<div>Route Was Not Found</div>'
};
Vue.use(VueRouter);
const routes = new VueRouter({
mode: 'history',
hashbang: false,
linkActiveClass: 'active',
base: '/jokes',
routes: [
{ path: '/', adminOnly: false, component: Main },
{ path: '/about', adminOnly: false, component: About },
{ path: '*', adminOnly: false, component: NotFoundException }
]
});
routes.mode = 'html5';
routes.beforeEach((to, from, next) => {
// CHECK IF ADMINONLY EXISTS
next();
});
export default routes;
I did get a solution by adding a mixin of adminOnly.js which has the following code in it:
But then again, the mixin has to be added to each component if I was to redirect the user to the login page if not admin.
//Just a test
var isAdmin = false;
export default {
beforeRouteEnter (to, from, next) {
if(!isAdmin) {
next((vm) => {
vm.$router.push('/login');
});
}
}
}
Yes there is better way to handle this. Every route object can have meta field. Just wrap adminOnly property in meta object:
routes: [
{ path: '/', meta: { adminOnly: false }, component: Main },
{ path: '/about', meta: { adminOnly: false }, component: About },
{ path: '*', meta: { adminOnly: false }, component: NotFoundException }
]
Check route for admin rights:
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.adminOnly)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
}
}
For more please check docs and I created little example on jsFiddle
Related
I have a problem, where when I use Vue Router for navigation, components don't disappear, the new one just places on top of old one.
My router file
import {createRouter, createWebHistory} from '#ionic/vue-router';
import {RouteRecordRaw} from 'vue-router';
import {AuthManager} from "#/functions/AuthManager";
import HomePage from '#/views/MainPage.vue';
import LoginScreen from '#/views/auth/LoginScreen.vue';
import component from "*.vue";
import RegistrationScreen from "#/views/auth/RegistrationScreen.vue";
import MainPage from "#/views/MainPage.vue";
const routes: Array<RouteRecordRaw> = [
{
path: '',
redirect: '/homepage',
},
{
path: '/login',
name: 'Login',
component: LoginScreen,
meta: {
requiresAuth: false
}
},
{
path: '/register',
name: 'Register',
component: RegistrationScreen,
meta: {
requiresAuth: false
}
},
{
path: '/home',
name: 'MainPage',
component: MainPage,
meta: {
requiresAuth: true
}
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
})
//code from https://stackoverflow.com/a/52663166 and modified to fit my needs
router.beforeEach(async (to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!await AuthManager.isLoggedIn() && to.name != "Login") {
next({name: 'Login', hash: '#forced'});
} else if ((to.name == "Login" || to.name == "Register") && await AuthManager.isLoggedIn()) {
next({name: 'Homepage'});
} else {
next() // go to wherever I'm going
}
} else {
next() // does not require auth, make sure to always call next()!
}
})
export default router
How I navigate
<ion-text #click="() => router().push('/register')" style="cursor: pointer" class="ion-padding-top">Nemáte účet? Zaregistrujte se</ion-text>
Image of components stacked on top of each other
I can't find a way to make old component disappear. Where Am I doing something wrong?
I don't understand why i doesn't recognise the next function whereas i followed a similar video implementing this and it worked with no errors
I don't understand why i doesn't recognise the next function whereas i followed a similar video implementing this and it worked with no errors
I don't understand why i doesn't recognise the next function whereas i followed a similar video implementing this and it worked with no errors
import Dashboard from "./Pages/Dashboard.vue";
import Customers from "./Pages/Customers.vue";
import EditProfile from "./Pages/EditProfile.vue";
import Insurance from "./Pages/Insurance.vue";
import Activations from "./Pages/Activations.vue";
import Login from "./Pages/Login.vue"
import ForgotPassword from "./Pages/ForgotPassword.vue"
import MyDashboard from "./Pages_cus/MyDashboard.vue";
import MyActivations from "./Pages_cus/MyActivations.vue";
import MyEditProfile from './Pages_cus/MyEditProfile.vue';
import NotFound from './Pages/NotFound.vue';
import NetworkError from './Pages/NetworkError.vue'
import { createRouter, createWebHistory } from "vue-router";
const routes = [
{
name: "MyDashboard",
component: MyDashboard,
path: "/my-dashboard",
meta: {
requiresAuth: true,
}
},
{
name: "MyActivations",
component: MyActivations,
path: "/my-activations",
},
{
name: "MyEditProfile",
component: MyEditProfile,
path: "/my-edit-profile",
},
{
name: "Dashboard",
component: Dashboard,
path: "/dashboard",
meta: {
requiresAuth: true,
}
},
{
name: "Customers",
component: Customers,
path: "/customers",
},
{
name: "EditProfile",
component: EditProfile,
path: "/edit-profile",
},
{
name: "Insurance",
component: Insurance,
path: "/insurance",
},
{
name: "Activations",
component: Activations,
path: "/activations",
},
{
name: "Login",
component: Login,
path: "/",
meta: {
requiresAuth: true,
}
},
{
name: "ForgotPassword",
component: ForgotPassword,
path: "/forgot-password",
},
{
name: "404Resource",
component: NotFound,
path: '/404/:resource',
props:true
},
{
name: "NetworkError",
component: NetworkError,
path: '/network-error'
},
{
name: "NotFound",
component: NotFound,
path: '/:catchAll(.*)'
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
router.beforeEach((to, next)=>{
if (to.matched.some(record => record.meta.requiresAuth)) {
if (localStorage.getItem('token') == null) {
console.log('Hello JS')
next({
path: '/',
params: { nextUrl: to.fullPath }
}) // I get the error at this level it doesn't recognise next as a function
}
else{
next();
}
}
else {
next()
}
})
export default router;
[Screenshot of code in VS code][1]
[Screenshot of code in browser
<!-- begin snippet: js hide: false console: true babel: false -->
import Dashboard from "./Pages/Dashboard.vue";
import Customers from "./Pages/Customers.vue";
import EditProfile from "./Pages/EditProfile.vue";
import Insurance from "./Pages/Insurance.vue";
import Activations from "./Pages/Activations.vue";
import Login from "./Pages/Login.vue"
import ForgotPassword from "./Pages/ForgotPassword.vue"
import MyDashboard from "./Pages_cus/MyDashboard.vue";
import MyActivations from "./Pages_cus/MyActivations.vue";
import MyEditProfile from './Pages_cus/MyEditProfile.vue';
import NotFound from './Pages/NotFound.vue';
import NetworkError from './Pages/NetworkError.vue'
import { createRouter, createWebHistory } from "vue-router";
const routes = [
{
name: "MyDashboard",
component: MyDashboard,
path: "/my-dashboard",
meta: {
requiresAuth: true,
}
},
{
name: "MyActivations",
component: MyActivations,
path: "/my-activations",
},
{
name: "MyEditProfile",
component: MyEditProfile,
path: "/my-edit-profile",
},
{
name: "Dashboard",
component: Dashboard,
path: "/dashboard",
meta: {
requiresAuth: true,
}
},
{
name: "Customers",
component: Customers,
path: "/customers",
},
{
name: "EditProfile",
component: EditProfile,
path: "/edit-profile",
},
{
name: "Insurance",
component: Insurance,
path: "/insurance",
},
{
name: "Activations",
component: Activations,
path: "/activations",
},
{
name: "Login",
component: Login,
path: "/",
meta: {
requiresAuth: true,
}
},
{
name: "ForgotPassword",
component: ForgotPassword,
path: "/forgot-password",
},
{
name: "404Resource",
component: NotFound,
path: '/404/:resource',
props:true
},
{
name: "NetworkError",
component: NetworkError,
path: '/network-error'
},
{
name: "NotFound",
component: NotFound,
path: '/:catchAll(.*)'
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
router.beforeEach((to, next)=>{
if (to.matched.some(record => record.meta.requiresAuth)) {
if (localStorage.getItem('token') == null) {
console.log('Hello JS')
next({
path: '/',
params: { nextUrl: to.fullPath }
}) // I get the error at this level it doesn't recognise next as a function
}
else{
next();
}
}
else {
next()
}
})
export default router;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
[1]: https://i.stack.imgur.com/Y9D08.png
[2]: https://i.stack.imgur.com/n9ERj.png
next is the third argument for the beforeEach function, so it should be:
beforeEach((to, from, next)) => {...
While you're using the next function correctly here (ensuring that it's called exactly once), it is currently deprecated: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0037-router-return-guards.md#motivation
It's now suggested to use 1 or 2 arguments and return a boolean value to indicate whether or not to proceed, or a route to redirect to:
router.beforeEach((to)=>{
if (to.matched.some(record => record.meta.requiresAuth)
&& localStorage.getItem('token') == null) {
//redirect
return {
name: '/',
query: { nextUrl: to.fullPath }
}
}
return true; //proceed (equivalent of next())
});
I'm just learning Vue3 and trying to do some routing, but I'm getting an error message that makes no sense.
Maybe it's related to some kind of nested routing, but I also tried to do children and it didn't want to work.
This works:
import { createRouter, createWebHistory } from 'vue-router';
import HomePage from '../home/HomePage.vue';
import FetchAccount from '../nonPrimaryADAccounts/FetchAccount.vue';
import CreateADAccount from '../nonPrimaryADAccounts/CreateADAccount.vue';
export default createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'Home',
component: HomePage,
},
{
path: '/FetchAccount',
name: 'FetchAccount',
component: FetchAccount,
},
{
path: '/CreateADAccount',
name: 'CreateADAccount',
component: CreateADAccount,
},
],
});
And this does not:
import { createRouter, createWebHistory } from 'vue-router';
import HomePage from '../home/HomePage.vue';
import FetchAccount from '../nonPrimaryADAccounts/FetchAccount.vue';
import CreateADAccount from '../nonPrimaryADAccounts/CreateADAccount.vue';
export default createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'Home',
component: HomePage,
},
{
path: '/NonPrimaryADAccount/FetchAccount',
name: 'FetchAccount',
component: FetchAccount,
},
{
path: '/NonPrimaryADAccount/CreateADAccount',
name: 'CreateADAccount',
component: CreateADAccount,
},
],
});
Error message:
4:29 error Unable to resolve path to module '../nonPrimaryADAccounts/CreateADAccount.vue' import/no-unresolved
If you need nested path the recommended approach is to use a function to generate the routes with the prefix:
const withPrefix = (prefix, routes) =>
routes.map( (route) => {
route.path = prefix + route.path;
return route;
});
export default createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'Home',
component: HomePage,
},
...withPrefix('/NonPrimaryADAccount',[
{
path: '/FetchData',
name: 'FetchData',
component: FetchData,
},
{
path: '/CreateADAccount',
name: 'CreateADAccount',
component: CreateADAccount,
},
]),
]
ONLY ON SAFARI BROWSER.
When I manually write the url on navigation bar after logged in, ex: "http://x.x.x.x:8080/gestione", the browser loses the vuex store state (so does the gest_user module with the currentUser) and redirect to login component, I'M USING VUEX-PERSISTEDSTATE:
routes:
const routes = [
{
id: "login",
path: "/login",
name: "login",
component: Login,
meta: {
...meta.default
}
},
{
id: "home",
path: "/",
name: "homeriluser",
component: HomeUtente,
meta: {
...meta.public, authorize: [Role.user, Role.admin]
},
},
{
id: "gestione",
path: "/gestione",
name: "gestrilevazioni",
component: GestRils,
meta: {
...meta.admin, authorize: [Role.admin]
}
},
{
path: "/modifica",
name: "modificaril",
component: EditRil,
meta: {
...meta.public, authorize: [Role.user, Role.admin]
}
},
{
path: "*",
name: "page404",
component: Pagenotfound,
meta: {
...meta.public
}
}
];
my router:
import Vue from 'vue';
import VueRouter from 'vue-router';
import routes from "./router";
import store from "#/store/index"
Vue.use(VueRouter);
const router = new VueRouter({
routes,
mode: "history"
});
router.beforeEach(async (to, from, next) => {
// redirect to login page if not logged in and trying to access a restricted page
const { auth } = to.meta;
const { authorize } = to.meta;
const currentUser = store.state.gest_user;
if (auth) {
if (!currentUser.username) {
// not logged in so redirect to login page with the return url
return next({ path: '/login', query: { returnUrl: to.path } });
}
// check if route is restricted by role
if (authorize && authorize.length && !authorize.includes(currentUser.roles)) {
// role not authorised so redirect to home page
return next({ path: '/' });
}
}
next();
});
export default router;
my store:
import createPersistedState from "vuex-persistedstate";
Vue.use(Vuex);
Vue.prototype.$http = axios;
Vue.prototype.axios = axios;
const debug = process.env.NODE_ENV !== "production";
const customPersist = createPersistedState({
paths: ["gest_user", "gest_rilevazione.rilevazione"],
storage: {
getItem: key => sessionStorage.getItem(key),
setItem: (key, value) => {
sessionStorage.setItem(key, value)
},
removeItem: key => sessionStorage.removeItem(key)
}
});
const store = new Vuex.Store({
modules: {
pubblico: pubblico,
amministrazione: amministrazione,
loading_console: loading_console,
login_console: login_console,
gest_itemconc: gest_itemconc,
gest_rilslave: gest_rilslave,
gest_rilmaster: gest_rilmaster,
sidebar_console: sidebar_console,
gest_user: gest_user,
gest_newril: gest_newril,
gest_rilevazione: gest_rilevazione
},
plugins: [customPersist],
strict: debug
});
export default store;
Can anyone tell me why this happens?
You are probably using browser's local storage to persist data. Could you check if local storage is enabled in your Safari browser?
I have a problem, which seemed to be simple but now is not so simple (for me):
I have set up a Vue project with the vue-cli (Router, VueX, PWA). I have set up some routes as always (following straight the recommendations of the documentation) and some state-fields in VueX:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '#/views/Home.vue'
import Login from '#/views/Login.vue'
import Logout from '#/components/functional/Logout.vue'
import Datapoints from '#/views/Datapoints.vue'
import store from '../store'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
meta: {
requiresAuth: true
}
},
{
path: '/login',
name: 'login',
component: Login,
meta: {
requiresGuest: true
}
},
{
path: '/logout',
name: 'logout',
component: Logout
},
{
path: '/project/:id',
name: 'project',
component: Datapoints
}
]
const router = new VueRouter({
mode: 'history',
routes
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.getters.isAuthenticated) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next()
}
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresGuest)) {
if (store.getters.isAuthenticated) {
next({
path: '/',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next()
}
})
export default router
In my Views / Components, i use the push method on the $router instance, to rote programatically, like this:
this.$router.push({ name: 'home', params: { status: project.response.status, message: project.response.data.error }})
, where project is the result of an awaited axios HTTP request.
My Problem
Every time i push programatically a new route, or use the router-view element, my page reloads (what i want to prevent in a SPA / PWA ...)
My Vue instance:
new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app');
I would be happy if anynoe could help me out to not reload the page on every route change with the Vue router.
I think the reload behavior is related to the history mode of your router
const router = new VueRouter({
mode: 'history',
routes
})
You can try remove the history mode and see what happens. If you want to keep it, please check with the history mode doc to see if all settings have been done correctly.
https://router.vuejs.org/guide/essentials/history-mode.html.
Hope this helps.
you can try using vuex-persistedstate to maintain data in store an it won't change whenever the page is refreshed.
`import createPersistedState from "vuex-persistedstate
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
});
Visit https://www.npmjs.com/package/vuex-persistedstate