Vue JS - Find the router history -1 - vue.js

Is it possible with Vue2 to see where...
this.$router.go(-1)
Will take you?
We have a use case to redirect the user to last page they were on after they signed in, unless that is the forgot your password page. In that case we would want to send them back to the home page.
What is the best way to do this?

Vue 2 with Vue Router 3
You could use beforeRouteEnter navigation guard to track the previous route (stored in from):
export default {
beforeRouteEnter(to, from, next) {
next(vm => {
vm._backRoute = from.path
})
},
methods: {
goBack() {
if (this._backRoute === '/reset-password') {
this.$router.push({ name: 'Home' })
} else {
this.$router.go(-1)
}
}
}
}
demo 1
Vue 3 with Vue Router 4
You could read window.history.state.back to see what the back-state would be beforehand:
export default {
methods: {
goBack() {
if (window.history.state.back === '/reset-password') {
this.$router.push({ name: 'Home' })
} else {
this.$router.go(-1)
}
}
}
}
demo 2

Related

Prevent route change within Vue compnent

Is it possible to prevent a route change within a Vue Component (not within my router file)?
My situation uses the same component, but the URL changes (/users/1 -> /users/2)
Vue.extend({
data: () => ({
active: true
}),
beforeRouteLeave(to, from, next){
if (this.active) {
// do not redirect
} else {
next();
}
}
})
My understanding is that this doesn't work when navigating the URL but the View/Component stays the same.
I need to use beforeRouteUpdate instead of beforeRouteLeave as stated in the docs
beforeRouteUpdate(to, from, next) {
if (this.active) {
next(false);
} else {
next();
}
},
If I'm using beforeRouteUpdate route url path in the browser not getting update, so I used beforeRouteLeave which is updating url and stop reloading same page.
beforeRouteLeave(to, from, next) {
if (this.active) {
next(false);
} else {
next();
}
}

Vue render a component two times

When I logged in the app and select edit some item, they make a $router.push to the edit view, the problem is that they render the component two times, I figured this out by doing a console.log on mounted(){}.. However, if I reload the page and click edit other time they make the render correctly, only one time.
This is the relevant code:
//listItemsView script
editItem(item) {
this.$router.push({ name: 'editPolicy', params:{policyTest: item}})
},
//editItemView script
export default {
props:{
policyTest:{
type: Object,
required: true,
}
mounted(){
console.log(this.policyTest);
console.log('entra');
},
}
//router script
{
path: '/editPolicy/',
name: 'editPolicy',
component: () => import('../views/policies/editPolicy.vue'),
props: true,
meta:{requireAuth:true}
}
router.beforeEach((to, from, next) => {
const user = auth.currentUser;
if(user !== null){
user.getIdTokenResult(true)
.then(function ({
claims
}) {
if (to.name === 'NewClient' && !claims.permissions.includes('Agregar Cliente')) {
next({name: 'notFoundPage'});
}else{
//In this case the router execute this next()
next()
}
})
} else {
if (to.matched.some(record => record.meta.requireAuth)) {
next({name: 'SignIn'});
} else {
next()
}
}
})
//html
<td class="text-left">
<v-icon small class="mr-2" #click="editItem(item)">fas fa-edit</v-icon>
</td>
i solved the problem, I'm use firebase authentication and in the main.js i'm detecting the user state change and for error i was creating two vue instances, one when start up the App and other when the user attemp to make their logging.. solved, thanks

(Vue Router) Push params when on a certain route

I have a component, which has programmatic routing based on external data.
The external data is fetched in the App.vue component and used in child components as props.
The data is used in the child component like this:
props: {
externalData: Array
},
computed() {
data() {
return this.externalData
}
}
Here is my router.js (excerpt)
const routes = [
{
path: "/:hae?",
name: "Home",
component: Home
},
{
path: "*",
name: "NotFound",
component: NotFound
}
];
And my Home.vue with the $router.push method (excerpt):
created() {
if (this.$route.path === "/") {
this.$router.push({
params: {
hae: this.data[0].id
}
});
}
},
So here is what i want to achieve:
This is my example array: [{hae: "hae001"}, {hae: "hae002"}, {hae: "hae003"} ...]
When you navigate to https://website.com/ i want the router to redirect you to a param which is the first element of the array, but if you navigate to somewhere else which is not existing in the array (e.g. /something) i want the router to render my NotFound.vue component.
What am i missing?
created() {
const firstDataElementExists = this.data && this.data[0] && this.data[0].hae
if (!firstDataElementExists) {
this.$router.push('/404')
return
}
const isRootPath = this.$route.path === '/'
if (isRootPath) {
this.$router.push(this.data[0].hae)
return
}
const pathIsInData = !!this.data.find(d => d.hae === p)
if (!isRootPath && !pathIsInData) {
this.$router.push('/404')
}
}

How to set beforeResolve navigation guard in Nuxt.js

Is there a way to add beforeResolve navigation guard in nuxt.config.js?
My nuxt.config.js
module.exports {
...
router: {
beforeResolve(to, from, next) {
if (this.$store.getters.isLoggedIn)
next('/resource')
}
}
...
}
But its never gets called!
I've been trying to achieve a redirection before the component is mounted based on the users logged in state on the vuex store.
You have 2 options for this. You can set a global rule via the middleware or in the respective page.
// middleware/route-guard.js
export default function ({ app }) {
app.router.beforeResolve((to, from, next) => {
if (app.store.getters.isLoggedIn) {
next('/resource')
} else {
next();
}
});
}
// Nuxt Page Component
export default {
beforeResolve (to, from, next) {
if (this.$store.getters.isLoggedIn) {
next('/resource')
} else {
next();
}
}
}

How to setup vuex and vue-router to redirect when a store value is not set?

I'm working with the latest versions of vue-router, vuex and feathers-vuex and I have a problem with my router.
What I'm doing is to check if a route has the property "requiresAuth": true in the meta.json file. If it does then check the value of store.state.auth.user provided by feathers-vuex, if this value is not set then redirect to login.
This works fine except when I'm logged in and if I reload my protected page called /private then it gets redirected to login so it seems that the value of store.state.auth.user is not ready inside router.beforeEach.
So how can I set up my router in order to get the value of the store at the right moment?
My files are as follow:
index.js
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store'
const meta = require('./meta.json')
// Route helper function for lazy loading
function route (path, view) {
return {
path: path,
meta: meta[path],
component: () => import(`../components/${view}`)
}
}
Vue.use(Router)
export function createRouter () {
const router = new Router({
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
routes: [
route('/login', 'Login')
route('/private', 'Private'),
{ path: '*', redirect: '/' }
]
})
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
if (!store.state.auth.user) {
next('/login')
} else {
next()
}
} else {
next()
}
})
return router
}
meta.json
{
"/private": {
"requiresAuth": true
}
}
I fixed the issue by returning a promise from vuex action and then run the validations
router.beforeEach((to, from, next) => {
store.dispatch('auth/authenticate').then(response => {
next()
}).catch(error => {
if (!error.message.includes('Could not find stored JWT')) {
console.log('Authentication error', error)
}
(to.meta.requiresAuth) ? next('/inicio-sesion') : next()
})
})