I'm looking for a smart way to handle in-page anchors with Vue Router. Consider the following:
<router-link to="#app">Apply Now</router-link>
<!-- some HTML markup in between... -->
<div id="app">...</div>
The "scroll to anchor" behavior described in the docs works fine except:
div id="app"
. Now scroll away from the div
back to the anchor and try clicking it again -- this time you will not jump down to the div
. In fact, the anchor will retain the class router-link-active
and the URL will still contain the hash /#app
;This is very unfortunate from the UX perspective because a potential customer has to manually scroll all the way down again to reach the application section.
I was wondering if Vue Router covers this situation. For reference, here's my router:
export default new VueRouter({
routes,
mode: 'history',
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return { selector: to.hash }
} else if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 }
}
}
})
I haven't found anything in the resources to solve your issue but you could utitlize the $route.hash
in your mounted
hook of the component that holds your <router-view></router-view>
to solve the refresh issue.
<script>
export default {
name: 'app',
mounted: function()
{
// From testing, without a brief timeout, it won't work.
setTimeout(() => this.scrollFix(this.$route.hash), 1);
},
methods: {
scrollFix: function(hashbang)
{
location.hash = hashbang;
}
}
}
</script>
Then to solve the issue of second clicks you could use the native
modifier and bind to your <router-link></router-link>
. It's a fairly manual process but will work.
<router-link to="#scroll" @click.native="scrollFix('#scroll')">Scroll</router-link>
There may also be something you could do with the router's afterEach
method but haven't figured that out yet.