router is undefined in vuejs - vue.js

I create done vue js app. In which i have main index.js file for routes and i made different route file for other view and all my child file extend in main index.js route file.
index.js (Main route file)
Below I import my child routes in this file
import test1 from './test1'
import test from './test'
My child route file test1
export default [{
path: '/roles',
component: Layout2,
children: [{
path: '/',
component: () => import('#/views/test/test1'),
meta: {
auth: true
},
beforeEnter(to, from, next) {
if(checkPermission("readUser")){
router.push({
name: 'unauthorized'
})
}
}
}
}]
}]
Now issue is i am trying push unauthorized in url by using before route, but it gives me error like router is not defined. How can i solve this issue?

I think you should creater router instance first, and export it.
export const router = new VueRouter(routes)
const routes = {
path: '/roles',
component: Layout2,
... etc.
}
Then import router into main js file.

Related

Process 404 page when there is no parameter in Vue

Dynamic routing is in use.
If there is no device data in vuex, I want to go to 404 page.
How should I implement it?
router/index.js
const routes = [
{
path: '/',
name: 'Main',
component: Main
},
{
path: '/:device',
name: 'Detail',
component: Detail,
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
},
]
When the device-detail page is implemented as follows, it does not move to the 404 page.
const deviceName = route.params.device
const storedDeviceList = computed(() => store.state.stationName)
if (!storedDeviceList.value.includes(deviceName)) {
router.push({
name: 'NotFound'
})
}
I think the first problem is, that you declare router two times in your project, according to your github repo. You declared your routes in your router/index.js and imported it into your main.js. So importing it again in About.vue from vue-router instead of router.js causes, that this instance has no routes. The second problem is the same with your store, as you import store/index.js to your main.js but import a new instance from vuex to your About.vue.
If you would use the composition API, you could call the already in main.js imported modules with this, like:
this.$router.push({
name: 'NotFound'
})
You also would get your states from your store like this:
this.$store.state.stationName
So, in composition API, use something like this in your About.vue:
<script>
export default {
methods: {
checkDevice() {
if (!this.$store.state.deviceList.includes(this.$route.params.device)) {
this.$router.push({
name: 'NotFound'
})
}
}
},
created() {
this.checkDevice()
}
}
</script>

Redirect to specific url in case of wrong url in vuejs

I have two separate routing files where I am importing the component and defining their routing in each of its file and using it in index.js file. Here are my files code:
//router1.js
import Layout1 from 'Layouts/Panel.vue';
const Users = () => import('Views/Users.vue');
const Reports = () => import('Views/Reports.vue');
export default {
path: '/layout1',
component: Layout1,
redirect:'/layout1/reports',
children:[
{
path: 'reports',
component: Reports,
name:'Reports'
},
{
path: 'users',
component: Users,
name:'Users'
}
]
}
//router2.js
import Layout2 from 'Layout/Panel2';
const Demo1 = () => import('Views/Demo1');
const Demo2 = () => import('Views/Demo2');
export default {
path: '/',
component: Layout2,
redirect:'/demo1',
children:[
{
path: '/demo1',
component: Demo1
},
{
path: '/demo2',
component: Demo2
}
]
}
// index.js
import Vue from 'vue'
import Router from 'vue-router'
import router1 from './router1';
import router2 from './router2';
const NotFound = () => import('Views/NotFound.vue');
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
router1,
router2,
{
path: '*',
component: NotFound,
name:'NotFound',
},
]
})
Now, I want to redirect to specific url i.e "not-found" in case of wrong URL. In "NotFound" component I am adding below line of code in mounted lifecycle hook which redirects to URL "not-found".
this.$router.replace({ path: 'not-found' });
But if URL is having parameters or query string it will append to it. For e.g- http://localhost:8080/home/not-found
What I want is that it only shows http://localhost:8080/not-found How should I achieve this. Please help. Thanks!
try this in your mounted function. worked on my side.
this.$router.push({path: '/not-found'})

Vue: beforeEach is not a function

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

Vue Router dependency missing

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'
});

Vuejs large application lazy loading dynamic components

I'm trying to build a vuejs application which will have hundreds if not thousands of "form" or "page" components that all get swapped out inside a dynamic <component is=''> tag. The problem is having to import each component. Is there a way to dynamically import components based on a route parameter? So far I have the following but it doesn't work:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const Hello = resolve => require(['#/components/Hello.vue'], resolve)
export default new Router({
routes: [{
path: '/',
name: 'Hello',
component: Hello
}, {
path: '/:name',
name: 'Dynamic',
component : {
template: '<component :is="$route.params.name"></component>',
watch: {
'$route': function(to) {
window[to.params.name] = resolve => require(['#/components/' + to.params.name + '.vue'], resolve)
Vue.component(to.params.name, window[to.params.name])
console.log(to.params.name)
}
}
}
}]
})
One way to do it, assuming all components are stored in a single directory (technically they can be stored anywhere as long as the loader file grabs and imports them).
import Vue from 'vue'
import Router from 'vue-router'
import Components from './components'
Vue.use(Router)
const Hello = resolve => require(['#/components/Hello.vue'], resolve)
export default new Router({
routes: [{
path: '/',
name: 'Hello',
component: Hello
}, {
path: '/:name',
name: 'Dynamic',
component : {
template: '<component :is="Components[$route.params.name]"></component>'
}
}]
})
Then inside ./components/index.js the following assuming all your components are .vue files:
const files = require.context('.', false, /\.vue$/)
const modules = {}
files.keys().forEach((key) => {
modules[key.replace(/(\.\/|\.vue)/g, '')] = files(key)
})
export default modules
I haven't tested this implementation, but the approach to loading the directory files is how I use it in some areas where I have a dynamic number of components located in a folder that can change over time (say as more modules get installed into the application and you don't want to have to update the supportive frontend code every time).