Best way to check what page you're on in Vue.js - javascript

I have
these simple route/URL when I am in a car details page
http://localhost:8080/car/1
I am using vue2; what is the best way to check if I am on a car page?
I normally
would have checked for the first segment of the URL, but I wasn't sure if that is the best future-proof approach.
Questions
Should I use JS to detect what page I am ?
Should I use Vue functionality to access the router object?
Why would one decide to pick one over another?

You could provide a name for your route inside the routes definition like :
{
path: '/car/{id}',
name: 'car',
component: CarView
},
then access it using this.$route.name or you could parse the this.$route.path to get the name using String object methods

Perhaps, try using: router.currentRoute.path, where router is:
import Router from "vue-router";
Vue.use(Router);
const routes = [
{ path: "/", component: Home },
{ path: "/test1", component: Test1 },
{ path: "/test2", component: Test2 }
];
const router = new Router({
routes
});
console.log('Current route: ', router.currentRoute.path);

Related

this.$route undefined in VueJS (without using arrows)

For some reason, this.$route is undefined for me. I have just started building my Vue application:
window.Vue = require('vue');
new Vue({
el : '#break-container',
data : {
break : null
},
methods : {
fetchBreak : function(){
console.log(this.$route); //undefined
},
},
mounted : function(){
this.fetchBreak();
},
});
I see a bunch of questions on SO about this, but every time the problem seems to be that they are using arrow notation.
In my case, when I do console.log(this) there is no $route key in the printed object at all. The keys ($attrs, $children, ... , $vnode, break).
What can I do to resolve this?
As I understand it, this.$route is only available on Vue instances if you register your router when you create your Vue app. Your code appears to be missing the router definition and subsequent initialisation on the Vue instance
new Vue({
el : '#break-container',
// Register your router
router: router,
data : {
break : null
},
methods : {
fetchBreak : function(){
console.log(this.$route); //undefined
},
},
mounted : function(){
this.fetchBreak();
},
});
See the sample code here for a full-fledged example. From the page above:
By injecting the router, we get access to it as this.$router as well as the current route as this.$route inside of any component
EDIT:
Pasting some example code from the link above for clarity. Note the steps 0-4 in the comments. Odds are, one of those steps are missing in your code :)
// 0. If using a module system (e.g. via vue-cli), import Vue and VueRouter
// and then call `Vue.use(VueRouter)`.
// 1. Define route components.
// These can be imported from other files
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. Define some routes
// Each route should map to a component. The "component" can
// either be an actual component constructor created via
// `Vue.extend()`, or just a component options object.
// We'll talk about nested routes later.
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. Create the router instance and pass the `routes` option
// You can pass in additional options here, but let's
// keep it simple for now.
const router = new VueRouter({
routes // short for `routes: routes`
})
// 4. Create and mount the root instance.
// Make sure to inject the router with the router option to make the
// whole app router-aware.
const app = new Vue({
router
}).$mount('#app')

url changes but angular does not navigate

I have 2 links like below. When I click on any one the first time, it navigates to it but when I click on the second link after that, the url changes but it does not navigate to it.
<li><a routerLink="/order/buyer" >Buyer</a></li>
<li><a routerLink="/order/seller">Seller</a></li>
These are my route configuration:
app.routing.module.ts
const routes: Routes = [
{
path: '',
pathMatch: 'full',
component: RootComponent,
},
{
path: '',
children: [
{
path: 'order',
loadChildren: './order/order.module#OrderModule',
}
]
}
order.module.ts
export const ROUTES: Routes = [
{
path: ':orderParty/:id',
component: OrderDetailComponent,
canDeactivate: [OrderDetailGuardService]
},
{
path: ':orderParty',
component: OrderListComponent
}
];
Tried several things, that out there but didn't work. What I have noticed is on the second click, the ngOnInit() of the 'OrderListComponent' does not get called.
You have a few options to solve this common issue in Angular, the most common one is using the solution on this GitHub thread:
https://github.com/angular/angular/issues/13831#issuecomment-319634921
constructor(private router: Router){
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function(){
return false;
}
this.router.events.subscribe((evt) => {
if (evt instanceof NavigationEnd) {
// trick the Router into believing it's last link wasn't previously loaded
this.router.navigated = false;
// if you need to scroll back to top, here is the right place
window.scrollTo(0, 0);
}
});
}
Another solution would to subscribe to your router params and handle change based on the new param like this article suggests:
this.activeRoute.params.subscribe(routeParams => {
this.loadUserDetail(routeParams.id);
});
https://medium.com/#mvivek3112/reloading-components-when-change-in-route-params-angular-deed6107c6bb
Yes, because route is same its the dynamic parameter that is changing. to read changed parameter you can inject router in construct and read parameter like
this.router.params.subscribe((params)=>{console.log(params)});
The route is pointing to same component hence its not re initializing.

how to manipulate the query string in vue.js using Vue router

I have a Vue.js app that has a tagging component. I'd like to add a url components like https://thisdomain.com/some?tag_ids=3,7,11 where a user can add tag_ids by toggling the tags in the UI.
While this is working for maintaining the tag_ids in the app. I'd also like to have them render in the browser url so that if the url is shared, it looks the same. I am using vue-router and I'd like to add the tag_ids to the query string but not force a new route in the path. I have tried something like:
this.$router.push({ path: '/', tag_ids: this.selectedTagIds })
and
this.$router.replace({ path: '/', tag_ids: this.selectedTagIds })
But this is not working. Any idea how to manipulate the query params via this.$router?
You can use params:
//navigation
this.$router.push({ name: 'some', params: { tag_ids: this.selectedTagIds } })
//route
{ path: '/some', name: 'some', component: Some }
Or, you can use query like this:
this.$router.push({ path: '/some', query: { tag_ids: this.selectedTagIds } })

Matching query param in vue routes

Is there any way to route by a query param? I would like to match the following route: site.com/?foo=123. I've tried things like
{ path: '/\?foo=[\d]*' }
without success.
Unfortunately, you can't match a query param in the path string of a route definition.
Vue Router uses path-to-regexp, and its documentation says:
The RegExp returned by path-to-regexp is intended for use with pathnames or hostnames. It can not handle the query strings or fragments of a URL.
You can use regular expressions to match on a route param by specifying the regex in parenthesis after the param name like so:
{ path: '/:foo([\d]*)' },
But, Vue Router's route params can't be in the query.
Here are some examples of the different route-matching features Vue Router provides.
If you really need to check the query of the url, you could use the beforeEnter handler to match the query manually and then reroute if it isn't the correct format:
const routes = [{
name: 'home',
path: '/',
component: Home,
beforeEnter(to, from, next) {
if (to.query.foo && to.query.foo.match(/[\d]*/)) {
next({ name: 'foo', query: to.query });
} else {
next();
}
}
}, {
name: 'foo',
path: '/',
component: Foo,
}];

Vue router inherit parent properties

I'm fairly new to vue.js and I'm currently trying to setup my different routes. I'm using sub routes, since the "logged in" user will have a different UI than a visitor.
Currently my setup is like this:
routes: [
{
path: '/auth',
name: 'auth',
component: test,
meta: {
auth: false
},
children: [
{
path: 'login',
name: 'login',
component: login
},
{
path: 'signup',
name: 'signup',
component: signup
}
]
},
{
path: '/user',
name: 'user',
component: test,
meta: {
auth: true
},
children: [
{
path: 'profile',
name: 'profile',
component: login
}
]
}
]
While this is working, I'm wondering why child routes don't take over the parents meta properties. Do I need to assign the meta.auth to each sub route? Or is there any way to inherit this?
Essentially in the router.beforeEach, I want to check if the user is authenticated correctly or not. But only on child routes of /user
I'm also coming from an angular background, so I'm used to nesting routes, not sure if this is the best way in Vue.
To answer my own question: https://github.com/vuejs/vue-router/issues/704
I didn't realise this was deprecated in Vue-router 2.0, it is possible to get the matched route and find the meta there.
With vue-router v.3 to match parent's meta (for example: in beforeEach() func. ) You need to use to.matched.some() like this:
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.auth)) {
// ...
next({name:'route-name'})
} else {
next()
}
}
https://router.vuejs.org/guide/advanced/meta.html

Categories