How to set the (correct!) savedPosition in Vue-router? - vue-router

For reasons I can't figure out the Y-value of the savedPosition never goes over 2000, even though window.pageYOffset reports me the correct Y-value if I ask it just before I push a new route.
console.log(window.pageYOffset) // tells me: 4233
this.$router.push({params:{id:newId}})
Hit backbutton.. router:
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
scrollBehavior: (to, from, savedPosition) => {
console.log('scrollBehavior',savedPosition) // tells me: 1557
}
routes: [ ... ]
}
The savedPositon seems to fluctuate beteen 1500 and 2000px, regardless how deep I am in the page. The window.pageYOffset always gives me the correct value.
I've tried returning a promise to wait a few seconds before scrolling, but that doesn't matter. If anyone has any idea's why this is or how to fix it, great, otherwise, somehow getting this window.pageYOffset value in the scrollBehavior would also be acceptable.
Also this concerns vue-router 3.x.. I'm migrating to vue-router 4.x in a few months time. So ideally it works in both or in 4.x only.

Related

Vue Router - Set default query parameters

I'm implementing an paginated list. Therefore I'm using query parameters like ?size=10. This query paramter needs to be always inside my URL (like /home?size=2).
This apporach is not working:
const routes = [{ path: "/home", query: { size: "10" }, components: MyPage }];
const router = createRouter({
history: createWebHistory(),
routes,
});
I thought it is instantiating the route with some parameters. Looking into the Routing section of vue devtools shows me an empty query object:
$route:/home
fullPath:"/home"
path:"/home
query:Object (empty)
hash:""
name:undefined
params:Object (empty)
matched:Array[0]
meta:Object (empty)
redirectedFrom:undefined
href:"/home
How can I set a default query param to my route?
Here is a proposal using the beforeEach NavigationGuard:
const routes = [{ path: "/home", name: "Home", components: MyPage }];
const router = createRouter({
history: createWebHistory(),
routes,
});
router.beforeEach((to, from) => {
if(to.name === "Home" && !to.query.hasOwnProperty("size")){
to.query.size = "10"
}
})
The idea is to add to the route a default query parameter for size when it is not there.
The only way to achieve this properly without defining the default value in every router.push() is probably with Navigation Gurads. You can use them to get the query-parameters that are currently in the url, add the default query-params you need and then return the new route.
Though I would not do it, this is probably the easiest way to achieve this.
And if you want to make them customizable via pinia/vuex you would need to set up a store and make a user input to change the setting.
Note: Pinia is most likely the better option, because it is newer and will still be supported far in the future

Vue2/Router3 — scrollBehavior not working

I'm trying to remember scroll position between routing pushes, NOT browser back/fwd navigation.
Case: on a long page of products, scrolling down and clicking on one of the items to see its details, then clicking a "back to list" button with a router push and (in my dreams) returning to where I was scrolled to on the product page.
This is my router. All the docs just give this basic config, but it doesn't work for me and I'm not sure if I need to add other logic in other components. Do I need to to save a 'savedPosition' in the state then get and set it in the router?
I'm also using beforeEach navigation guards but there isn't any scroll logic in there.
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
scrollBehavior(to, from, savedPosition) {
console.log("savedPosition", savedPosition);
if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
},
});

Base option in vue router

This issue has been discussed several times (1 - 2) but I still cannot get it to work. I'm transitioning our project to use vue in some parts. What I want to accomplish is:
If url starts with /v/, look into vue router and match path.
If url starts with anything other than /v/, ignore it (this view will be rendered by current framework from backend).
My router looks like:
const router = new Router({
base: '/v/',
mode: 'history',
routes: routes
});
Where routes are:
const routers = [
...
{
path: '/wholesale-catalogue/',
name: 'wholesale-catalogue',
component: () => import('./views/WholesaleCatalogue.vue')
}
...
]
The second option I tried is nesting the children routes:
const router = new Router({
mode: 'history',
routes: [
{ path: 'v', component: BaseView, children: routers }
]
});
The problem is that the router reroutes non /v/ urls into /v/ when clicked within the website, such as:
ourwebsite.com/home/ -> has some links on it, such as /about/. When you click on /about/ it actually goes to ourwebsite.com/about/ for a few seconds but then the url changes to /ourwebsite.com/v/about/. This leads to some annoyances as when you refresh the website, this url doesn't exist (on our current backend framework) so it will not render.

VueJS goBack from Dynamic Route

I have / and /items/:name
I go / then /items/iphone5 then /items/phone6
Then call $router.go(-1) and that direct me to / instead of /items/iphone5
What's wrong?
Update:
beforeRouteUpdate (to, from, next) {
this.toggleSideBar()
next()
}
this code works, but dunno why not adding history,
then I create a promise to solve
beforeRouteUpdate (to, from, next) {
this.toggleSideBar().then(() => next())
}
Maybe you uses replace option on your anchor.
please check out your tag has this property
<router-link :to="..." **replace**>
Then call $router.go(-1) and that direct me to / instead of /items/iphone5
go method is based on history API
go(-1) returns to previous entry stored in the current history entry
I go / then /items/iphone5 then /items/phone6
You have to inspect whether the history entry counts for your route or try using history mode
vue router default mode is hash.
const router = new VueRouter({
mode: 'history',
routes: [...]
})
Read docs for more info [Read caveats in the last and Server Side Rendering in first place if you have some time]

Vue router scrollBehavior returns same path for both to and from

I would like to check the to and from of the route path with scrollBehavior to manage the scroll behaviour.
global.router = new VueRouter({
routes,
scrollBehavior(to, from, savedPosition) {
console.log('>>> to', to);
console.log('>>> from', from);
switch (to.path) {
case '/in-list':
break;
case '/your-list':
break;
default:
return {x: 0, y: 0}
}
},
mode: 'history',
});
Suppose, I navigate from About page to the In-List or Your-list page, I would like to return {x: 0, y: 0}. However, when navigating between In-list or Your-list I would like no such behaviour.
However, both to and from return the same path. They both return the to.path so I cannot check where it was navigated from. What am I missing here?
Okay, so the problem was with my version. I was using ^2.2.1 and upgraded to the latest version 2.7.0. However, this issue was fixed in version 2.3.1.
I saw the issue in the closed issues of Vue-router. Hope this will help some one.