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>
Related
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.
Im trying to figure out why Vue.js routing, after I refresh my admin page re-directs back to the home component, only showing a blank page, and after a second refresh shows the home component again. I am still logged in as I can still go directly with the url to my admin-page. Meaning the session is still active. Is there a way to force the page to stay on the admin home page when I press F5? I tried things like history mode etc, but cant figure it out.
This is my router.js layout in the root and alos my main router file
import Vue from 'vue'
import Router from 'vue-router'
import firebase from "firebase/app";
import Home from './views/user/Home.vue'
import adminRoute from "./components/routes/admin-routes";
Vue.use(Router);
const router = new Router({
routes: [
{
path: '*',
redirect: '/',
},
{
path: '/',
name: 'home',
component: Home,
meta: {
requiresAuth: false,
}
},
...adminRoute
],
});
router.beforeEach((to, from, next) => {
if (to.matched.some(r => r.meta.requiresAuth === false)) {
next()
} else if (!firebase.auth().currentUser) {
next(false)
} else {
next()
}
});
export default router
and I have my admin-routes.js
import AdminHome from "../../views/admin/AdminHome";
import Users from "../../views/admin/Users";
const adminRoute = [
{
path: '/admin-home',
name: 'AdminHome',
component: AdminHome,
meta: {
requiresAuth: true
},
},
{
path: '/users',
name: 'Users',
component: Users,
meta: {
requiresAuth: true,
}
}
];
export default adminRoute;
I do want to mention that my main page is under views/user/Home.vue and my AdminHome page is views/admin/AdminHome.vue
This problem is return to the server not the built app
you have to manage your 404 not found root
Here you can find the solution
and if you work With Netlify you just create a file in the root of the project ( same place as package.json) name netlify.toml containing
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
in vue4 they did away with the 'next' argument(see here), this is working for me to send people back to the login page, where I'm using firebaseui, I have a simple boolean flag in my vuex store named "isAuthenticated" that I flip on when a user signs on.
NOTE: the following is a boot file for quasar v2 but the logic will
work where ever you have access to the store
import { computed } from 'vue'
export default ({ app, router, store }) => {
console.log('nav.js:')
const isAuthenticated = computed(() => store.state.auth.isAuthenticated)
console.log('isAuthenticated',isAuthenticated.value)
router.beforeEach((to, from) => {
console.log('nav.js:beforeEach:to',to)
console.log('nav.js:beforeEach:from',from)
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!isAuthenticated.value) {
console.log('nav.js:beforeEach:to.redirect')
return '/login'
}
}
})
}
I am building an app using Vue Router that uses an "external" site for login credentials. It essentially looks like this:
Home.Vue
<template>
</template>
<script>
export default {
name: "Home",
data() {
return {
}
},
created() {
window.location = 'https://third_party_site.com?nextpage=http://my_site.com/#/entry'
}
}
</script>
<style scoped>
</style>
This third_party_site.com handles auth and sends a JWT back as a query string in the resulting URL. When I try to use a navigation guard (as shown below) to get the query string, Vue router only looks in the router's history.
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/Home'
import Entry from '#/components/Entry'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/entry',
name: 'Entry',
component: Entry,
beforeEnter: (to, from, next) => {
console.log('to',to)
console.log('from',from)
console.log('next',next)
next()
},
meta: {
title: 'Entry'
}
},
]
})
The console prints the expected "to" location but the "from" location is the base path, "/", and there are no query parameters. How do I go about getting the "external" route so I can access the query parameters? The resulting console.log of "from" is below.
from
{name: null, meta: {…}, path: "/", hash: "", query: {…}, …}
fullPath: "/"
hash: ""
matched: []
meta: {}
name: null
params: {}
path: "/"
query: {}
__proto__: Object
Before asking, the app, in its current state, has to be built this way and I do not have access to the external site.
Wild shot in the dark here but the # in your nextpage query parameter is probably messing with the remote site.
What it will see is
QUERY => nextpage=http://my_site.com/
FRAGMENT => #/entry
so it will redirect back to http://my_site.com/ because it probably ignores any fragment.
You should encode the value correctly, eg
window.location = 'https://third_party_site.com/?nextpage=' +
encodeURIComponent('http://my_site.com/#/entry')
which will produce nextpage=http%3A%2F%2Fmy_site.com%2F%23%2Fentry
How can I display a router name in a component ?
Example:
const routes = [
{ path: '/documents', component: Documents, name:"Documents" ,props:true},
{ path: '/queries', component: Queries, name:"Queries", props:true}
]
I want to display the name property as a title in the component. Is this possible? how?
props:true will convert path parameters to properties:
{ path: '/documents/:name', component: Documents, name:"Documents", props:true},
You can use an object instead of true and then send in a string.
{ path: '/documents', component: Documents, name:"Documents", props:{ name:'Documents'}},
In your component, register the property
props: { name:String }
And then use it in a template like this:
<div>{{name}}</div>
You can also refer to the route name using the components $route object
<div>{{$route.name}}</div>
To specify title to a component you can use router's meta property, Link
const routes = [
{
path: '/documents',
component: Documents,
name:"Documents" ,
props:true,
meta: {
title: 'Documents'
}
},
{
path: '/queries',
component: Queries,
name:"Queries",
props:true,
meta: {
title: 'Queries'
}
}
]
In main.js,
import router from '#/routes'
router.beforeEach((to, from, next) => {
document.title = `Currently at - ${to.meta.title}`
next()
})
I am trying to modify an existing angular app to fit into the structure of this Starter Project. Anyway, so I have my app module with a submodule (tutorial). Which looks like this:
When landing on the root domain and then navigating with the router links to http://localhost:3000/tutorial/chapter/0, everything works fine. However, if I refresh the page or try to go directly to that link, I get the error:
Unhandled Promise rejection: Template parse errors:
'my-app' is not a known element:
1. If 'my-app' is an Angular component, then verify that it is part of this module.
2. If 'my-app' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '#NgModule.schema' of this component to suppress this message. ("
<body>
[ERROR ->]<my-app>
<div class="valign-wrapper">
<div class="preloader-wrapper active valign"): a#30:4 ; Zone: <root> ; Task: Promise.then ; Value: Error: Template parse errors:(…) Error: Template parse
So I believe this is happening because rather than that url linking to the appcomponent, with the tutorial submodule as a child, it's just linking to the TutorialModule, and then the <my-app></my-app> tags from the index.html aren't recognised. This worked before, so I am not sure what aspect of this new configuration has broken this.
Here is my app.routes.ts:
import { homeComponent } from './components/home/home.component';
import { pluginsComponent } from './components/plugins/plugins.component';
import { Routes, RouterModule } from '#angular/router';
const appRoutes: Routes = [
{ path: '', component: homeComponent },
{ path: 'tutorial', loadChildren: 'tutorial/tutorial.module', pathMatch: 'prefix'},
{ path: 'plugins', component: pluginsComponent }
];
export const appRoutingProviders: any[] = [];
export const routing = RouterModule.forRoot(appRoutes);
and my tutorial.routes.ts:
import { Routes, RouterModule } from '#angular/router';
import { tutorialComponent } from './tutorial.component';
import { chapterComponent } from './chapter/chapter.component';
const tutorialRoutes: Routes = [
{
path: 'tutorial',
component: tutorialComponent,
children: [
{ path: 'chapter/:id', component: chapterComponent },
{ path: '', redirectTo: 'chapter/0', pathMatch: 'full'},
]
}
];
export const tutorialRouting = RouterModule.forChild(tutorialRoutes);
finally in my app.ts where I define the express routes I have:
app.all(/^\/tutorial$/, (req, res) => {
res.redirect('/tutorial/');
});
app.use('/tutorial/', (req, res) => {
res.sendFile(resolve(__dirname, '../public/index.html'));
});
to serve the angular index for the tutorial component.
The whole repo is here
The issue was the index.html file, I had <base href="."> where it should have been <base href="/">. I have a bug report here
#micronyks already said this in the comment but what you need to do a setup your web server to redirect all requests to your index.html page. Then your app will load and navigate to your "deep" link.