Route change doesn't scroll to top, so Vue creator advises to use navigation guards. In the updated version:
Router.beforeEach(function (to, from, next) {
window.scrollTo(0, 0)
next();
})
Perfect, except it yields this fatal error in my app: ncaught TypeError: vue_router__WEBPACK_IMPORTED_MODULE_1__.default.beforeEach is not a function
Why?
Just in case here's my complete router.js file:
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import PastEvents from './views/PastEvents.vue'
import BasicPage from './views/BasicPage.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/past-events',
name: 'past-events',
component: PastEvents
},
{
path: '/basic-page',
name: 'basic-page',
component: BasicPage
}
]
})
Router.beforeEach(function (to, from, next) {
window.scrollTo(0, 0)
next();
})
You've capitalized Router, that's the class name. What you want to do is add your .beforeEach() to the instance of the router. You'll notice in the documentation that it's always a lowercase router they're adding the guards to.
Currently, you're immediately exporting the instance from the module, so you'll need to first add it to a variable when you create a new Router and then add your .beforeEach() clauses to it before finally exporting it.
const router = new Router({
...
})
router.beforeEach( ... )
export default router
Related
I have a vue-router that works as designed, but the moment I add the beforeEach() function to it, nothing appears in the <router-view> tags. Even if the beforeEach() function is empty, it still hides the content from the page. I there something else I need to do to make the <router-view> tag and router work with each other even with the beforeEach() function?
Here is the router:
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home,
meta: {
authenticatedRoute: false
}
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ './views/Login.vue'),
meta: {
authenticatedRoute: true
}
}
]
})
router.beforeEach((to, from, next) => {
// test
})
export default router;
And the <router-view> tag:
<v-content>
<router-view></router-view>
</v-content>
If your beforeEach fails to call next(), the route will not resolve.
With that in mind, a completely minimal beforeEach would be
router.beforeEach((to, from, next) => {
next()
})
From the documentation...
next: Function: this function must be called to resolve the hook.
...
Make sure to always call the next function, otherwise the hook will never be resolved.
Hello apologise for my question could be very dummy but i was not able to find correct answer in google. I dont have access to this.$router in Vue. From what i found it says vue inject router as dependecy to every component. But still my this.$route do not shows up. I'm using Vue version 3.2.1 and vue-router 3.0.1 (selected from CLI when project it's generated). Im alowed to navigate tho. Everything seems to be correctly just this dependency $router i dont have access to it.
I tryed to research in google everything but unsuccessfully. What i found it was only that which says vue inject router as dependency to every component still unsucesfull to find as property to my class $router. Everything else works good tho, i mean router link, router view just property to reach params or query or redirect is missing.
How did you initialize your vue-router module with Vue ?
It should be like this :
import Vue from 'vue'
import VueRouter from 'vue-router'
// Include plugin
Vue.use(VueRouter)
// Initialize your router
const vueRouter = new VueRouter({
routes: [] // your routes
})
// Send your router to your Vue top component
const app = new Vue({
el: '#my-app',
router: vueRouter,
render: h => h(App)
})
import Vue from 'vue';
import './plugins/vuetify'
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');
And i have separate file with my routes:
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
import Signin from './views/Users/Signin.vue';
import Signup from './views/Users/Signup.vue';
import Profile from './views/Users/Profile.vue';
import AddPlace from './views/WorldPlaces/AddPlace.vue';
import AllPlaces from './views/WorldPlaces/AllPlaces.vue';
import DetailsPlace from './views/WorldPlaces/DetailsPlace.vue';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/signup',
name: 'signup',
component: Signup
},
{
path: '/signin',
name: 'signin',
component: Signin
},
{
path: '/profile',
name: 'profile',
component: Profile
},
{
path: '/places/add',
name: 'addplace',
component: AddPlace
},
{
path: '/places/all',
name: 'allplaces',
component: AllPlaces
},
{
path: '/places/details/:id',
name: 'detailsplace',
component: DetailsPlace
}
// {
// path: '/about',
// name: 'about',
// // route level code-splitting
// // this generates a separate chunk (about.[hash].js) for this route
// // which is lazy-loaded when the route is visited.
// component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
// },
],
mode: 'history'
});
I am trying to access the Vuex store as shown in this article: here
I've wasted a good morning on what I am sure is going to be a simple typo, but It escapes me. Inside the beforeEach() => {} body, I get "store is not defined".
I am using the store from the LoginForm component, and it seems to be there. The Vuex tab in the chrome debugger shows the store contents that I expect. What am I doing incorrect?
Cut-n-paste from the critical code:
src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import LoginForm from '#/components/LoginForm'
import HomePage from '#/components/HomePage'
import store from '#/store'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{
path: '/login',
component: LoginForm
},
{
path: '/home',
component: HomePage,
meta: {requiresAuth: true}
}
]
})
router.beforeEach((to, from, next) => {
// store is undefined here
const IsAuthenticated = store.getters.IsAuthenticated()
if (to.matched.some(record => record.meta.requiresAuth) && !IsAuthenticated) {
next({path: '/login', query: { redirect: to.fullPath }})
} else {
next()
}
})
export default router
EDIT: The export from the store seems to be ok. By keeping a local reference to the imported store and referencing that, it works. Seems to be contextual in my use of beforeEach().
const lStore = store;
router.beforeEach((to, from, next) => {
// store is undefined here, lStore is good to go
const IsAuthenticated = lStore.getters.IsAuthenticated()
...
})
I have a very similar code and the only relevant difference seems to be that I import the store the following way in router/index.js:
import store from '#/store/index';
My entire router.js is:
import Vue from 'vue';
import Router from 'vue-router';
import ProjectPage from '#/pages/ProjectPage';
import store from '#/store/index';
Vue.use(Router);
const router = new Router({
routes: [
{
path: '/',
name: 'ProjectPage',
component: ProjectPage,
},
],
});
router.beforeEach((to, from, next) => {
// store is defined here
console.log(store);
debugger;
});
export default router;
This was a tail-chasing exercise in the grandest. The problem was that my getter was not called "IsAuthenticated" (and it also wasn't a function). I allowed myself to get duped by my debugger. Restoring all code back to the original post and changing the getter call to
correct
const IsAuthenticated = store.getters.isAuthenticated
incorrect
const IsAuthenticated = store.getters.IsAuthenticated()
In Chrome, putting a breakpoint on that line of code and attempting to inspect 'isAuthenticated' by hovering your mouse over the code yields the original indicated behavior, even though the line evaluates fine.
I also have similar case. On my case:
I have store with modules. So all modules imported on /store/index.js
On router /router/index.js, I import the store
and then use store getter on router work well
store/index.js
...
import auth from './modules/auth'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
auth
}
})
router/index.js
...
import store from '../store/index.js'
...
router.beforeEach(async (to, from, next) => {
console.log(store.getters['auth/isAuthenticated'])
next()
})
beforeEach hook for every route like in the docs:
My page should scroll to the top on route change.
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
window.scrollTo(0, 0)
next();
})
but my router has another structure and its not working:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import Contact from '#/components/Contact'
Vue.use(Router)
export default new Router({
beforeEach: (to, from, next) => {
window.scrollTo(0, 0)
next();
},
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/kontakt',
name: 'Contact',
component: Contact
},
]
})
Thanks in advance =)
Or is it better to use the .created hook on the components to scroll to the top of the page?
created() {
window.scrollTo(0, 0);
}
You can adapt your code to the structure required in the docs:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import Contact from '#/components/Contact'
Vue.use(Router)
// create object router with the valid initialization
const router = new Router({
routes: [{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}, {
path: '/kontakt',
name: 'Contact',
component: Contact
}, ]
});
// add the beforeEach hook
router.beforeEach((to, from, next) => {
window.scrollTo(0, 0);
next();
});
// export router as default
export default router;
I think you should put Router.beforeEach after creating router.
I'm trying to use vue-router to link url's to their corresponding components.
My issue is that only the root url ('/') can link to the correct component and any other url (e.g. '/first') does not link to their component. All of them link to the component which belongs to the '/' url.
When I use "a" tag in the vue file it will route to the right component - it's only when I input the url directly into the browser that it doesn't work
main.js:
import Vue from 'vue'
import router from './router/index.js'
Vue.use(ElementUI)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
// components: { App },
render: h => h(App)
})
index.js:
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '../components/Hello.vue'
import First from '../components/firstPage.vue'
import Login from '../components/logIn.vue'
Vue.use(Router)
const routes =[
{
path: '/',
component: Login
},
{
path:'/first',
component:Hello
}
]
const router = new Router({
routes
})
export default router
I think you can also try as below. It's works, just try it! You can add mode: 'hash', to give default # in all urls.
import Vue from 'vue';
import Router from 'vue-router'
import Hello from '../components/Hello.vue'
import First from '../components/firstPage.vue'
import Login from '../components/logIn.vue'
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'hash',
base: '/your_base_name_if_you_want',
linkActiveClass: 'active-tab', //if you w
routes: [
{
path: '/',
redirect: '/if_you_want_to_redirect',
name: 'Login', //Whatever
component: {
render (c) { return c('router-view'); }
},
children: [
{
path: '/',
component: Login
name: 'Login',
meta: { title: 'Your title name' }
},
{
path:'/first',
component:Hello
name: 'Hello',
meta: { title: 'Your title name' }
}
]
}
]
})
export default router
You can also remove it from your urls using:
var router = new VueRouter({
history: true
});
Hope this helps you!
The default mode for vue-router is hash mode
This is why you can't get the 'Hello' component when your url is '/first'. Instead you can try input '/#/first'.
If you want to use history mode like '/first', set the mode attribute for your route object like this.
const router = new Router({
mode: 'history',
routes
})
Hope it helps you.