Matching query param in vue routes - javascript

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,
}];

Related

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

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

vue-router sets wrong parameter after reloading

I have
// routes.js
{ path: '/posts', name: 'Posts', component: PostsView },
{
path: '/post/:post_id',
name: 'PostRead',
component: PostReadView,
},
{
path: '/post/cu/:post_id?',
name: 'PostCreateUpdate',
component: PostCreateUpdateView,
},
// PostCreateUpdate.vue
mounted: function() {
if( this.$route.params.post_id ) {
this.$store.dispatch('getPost', this.$route.params.post_id);
}
},
When I access the PostCreateUpdate via router-link like this
<router-link :to="{ name: 'PostCreateUpdate' }">Create</router-link>
It works with no problems as I see the parameter in the Vue Devtools isn't set, but when I access the URL by reloading or hard coding the url /post/cu/ the framework (I think) removes the trailing slash and treats cu as some /post/ parameter, thus, loading PostRead with post_id=cu and giving me something I don't want.
You need to always declare your most restrictive URIs first. Order matters, because Vue Router will go through your routes, and pick the first one that matches.
Invert your /post/:post_id route and /post/cu/:post_id? one:
// routes.js
{ path: '/posts', name: 'Posts', component: PostsView },
{
path: '/post/cu/:post_id?',
name: 'PostCreateUpdate',
component: PostCreateUpdateView,
},
{
path: '/post/:post_id',
name: 'PostRead',
component: PostReadView,
},

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

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

How do I match this in Backbone.js routes?

/story/:id
AND
/story/:id/:timestamp
I want both of these URLs to go to the same function in Backbone.js routes. (timestamp is optional)
What's the regex for this in Backbone.js?
Just define two routes:
routes: {
'story/:id': 'story',
'story/:id/:timestamp': 'story',
//...
}
The Backbone.Router.extend docs even include an example that is almost an exact match for your situation:
routes: {
//[...]
"search/:query": "search", // #search/kiwis
"search/:query/p:page": "search" // #search/kiwis/p7
},
And the routes documentation includes an example of a similar situation:
routes: {
//[...]
"folder/:name": "openFolder",
"folder/:name-:mode": "openFolder"
}

Categories