Vue router advanced props - vue.js

I'm trying to customize the props object passed by the router to a component.
In my routes I have:
{
path: '/base/fixed/:dynamic',
component: OfficeActions,
props: true
},
This allows me to access the dynamic prop inside de component. However, I would like to do something like this:
{
path: '/base/fixed/:dynamic',
component: OfficeActions,
props: {
custom: 'something_custom_for_this_route',
dynamic: dynamic // the dynamic parameter from the route (:dynamic)
}
},
Where I would be able to access trow props inside the component: custom and dynamic. The custom prop being defined in my route, and the dynamic prop being the value grabbed form the route :dynamic.
Is this possible? Any help is appreciated.
With the example above, I get an error since dynamic isn't define inside the props object.
I have also tried:
{
path: '/base/fixed/:dynamic',
component: OfficeActions,
props: {
custom: 'something_custom_for_this_route',
}
},
and
{
path: '/base/fixed/:dynamic',
component: OfficeActions,
props: {
default: true,
custom: 'something_custom_for_this_route',
}
},
With these I get dynamic as undefined inside the component.

As written in the documentation:
You can create a function that returns props.
And thus combine the parameters of both types:
{
path: '/base/fixed/:dynamic',
component: OfficeActions,
props: function(route) {
return Object.assign({}, route.params, {
custom: 'something_custom_for_this_route'
})
}
}
[ https://jsfiddle.net/uypveLhw/ ]

Related

How can I mix Boolean and Object Mode in vue router?

how can I mix Boolean and Object Mode in my Vue Router?:
props: true
with
props: { someRouteSpecificProps: "someValue"}
I need to also send props via router.push.
So:
//router
{
path: "somePath",
name: "someName",
props: { someRouteSpecificProps: "someSpecificValue" },
component: successAndLogoutPage,
},
//component
this.$router.push({
name: "someName",
query: this.$route.query,
params: {
ValueOnlyKnownInCompoent: 500000,
AnotherValueOnlyKnownInCompoent: "foo",
}
},
Using Vue 2, Js not ts.
Doing as I did, will ignore the props from the component. Doing props: true will use the props from the component but I still neet the someRouteSpecificProps directly in the router definition.
The solution is using the function mode:
props: (route) => {
return { someSpecificProps: 'value here', ...route.params };
},
In route the params are provided and can be provided to the props.
(Credit to #PerpetualWar from the vue discord, on whos advice the solution was formed)

Pass data through router to other component in vue

I am trying to pass data through router. My code is working but it shows data in url. I don't want that like as POST method.url should like /data-list . Also I want to catch passing value from component. Here I did not use vuex . Actually my job is to show message that task is done based on this data. I am using Laravel for backend. Thanks in advance
1st component
axios.post("/request/data", dataform).then(function (resp) {
app.$router.push({ path: "/data-list/" + resp.data.success });
});
routes
{
path: '/data-list/:message?',
name: 'dataList',
component: dataList,
meta: {
auth: true
}
},
Another component. Here I want to catch
mounted() {
var app = this;
app.message = app.$route.params.message;
}
So if I understand correctly, you are fetching data in some component and then you are doing a router-push to dataList component.
You want to access the data in dataList component.
Since you always want the route to be /dataList, do this in your routes file
{
path: '/data-list', //removing dynamic tag.
name: 'dataList',
component: dataList,
meta: {
auth: true
}
},
Then in the component where you do router push, add a handleClick like so.
handleClick() {
let data = {
id: 25,
description: "pass data through params"
};
this.$router.push({
name: "dataList", //use name for router push
params: { data }
});
}
}
Then in your dataList component you can access the data passed in the mounted like so :
mounted() {
let data = this.$route.params.data;
console.log("data is", data);
}
Working implementation attached below.
You can push router data in router like this.
this.$router.push({
name: "dataList",
params: { data: resp.data },
});
and in the routes you can define your route as
{
path: "/dataList",
name: "dataList",
props: true,
meta: { title: "Data list" },
component: () => import("path to datalist component")
},
and in the DataList.vue you can use props to get the data
export default {
props:['data'],
mounted(){
alert(this.data);
}
}

Vuejs Display a router name in Component

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

Invalid prop type from router params, expected Number got String

I am trying to collect id value from URL.
Previously I take help in this post.
In my index.js of router file I have below code:
{ path: '/word/:id',
name: 'word',
component: Word,
props: true,
},
In my component I have below code:
<script>
export default {
props: {
id: Number,
},
created() {
this.routeChanged();
},
watch: {
'id': 'routeChanged',
},
methods: {
routeChanged () {
console.log(this.id);
},
},
};
</script>
I am getting below error:
[Vue warn]: Invalid prop: type check failed for prop "id". Expected Number, got String.
That is the use case for Passing Props to Route Components with Function mode:
You can create a function that returns props. This allows you to cast parameters into other types, combine static values with route-based values, etc.
In your case, instead of specifying the route option with props: true, you would pass a function to the props option:
routes = [{
path: '/word/:id',
component: Word,
props: castRouteParams
}];
function castRouteParams(route) {
return {
id: Number(route.params.id),
};
}
Live example: https://codesandbox.io/s/8kyyw9w26l (click on the "Go to Test/3" link)

Passing props to Vue.js components instantiated by Vue-router

Suppose I have a Vue.js component like this:
var Bar = Vue.extend({
props: ['my-props'],
template: '<p>This is bar!</p>'
});
And I want to use it when some route in vue-router is matched like this:
router.map({
'/bar': {
component: Bar
}
});
Normally in order to pass 'myProps' to the component I would do something like this:
Vue.component('my-bar', Bar);
and in the html:
<my-bar my-props="hello!"></my-bar>
In this case, the router is drawing automatically the component in the router-view element when the route is matched.
My question is, in this case, how can I pass the the props to the component?
<router-view :some-value-to-pass="localValue"></router-view>
and in your components just add prop:
props: {
someValueToPass: String
},
vue-router will match prop in component
sadly non of the prev solutions actually answers the question so here is a one from quora
basically the part that docs doesn't explain well is
When props is set to true, the route.params will be set as the component props.
so what you actually need when sending the prop through the route is to assign it to the params key ex
this.$router.push({
name: 'Home',
params: {
theme: 'dark'
}
})
so the full example would be
// component
const User = {
props: ['test'],
template: '<div>User {{ test }}</div>'
}
// router
new VueRouter({
routes: [
{
path: '/user',
component: User,
name: 'user',
props: true
}
]
})
// usage
this.$router.push({
name: 'user',
params: {
test: 'hello there' // or anything you want
}
})
In the router,
const router = new VueRouter({
routes: [
{ path: 'YOUR__PATH', component: Bar, props: { authorName: 'Robert' } }
]
})
And inside the <Bar /> component,
var Bar = Vue.extend({
props: ['authorName'],
template: '<p>Hey, {{ authorName }}</p>'
});
This question is old, so I'm not sure if Function mode existed at the time the question was asked, but it can be used to pass only the correct props. It is only called on route changes, but all the Vue reactivity rules apply with whatever you pass if it is reactive data already.
// Router config:
components: {
default: Component0,
named1: Component1
},
props: {
default: (route) => {
// <router-view :prop1="$store.importantCollection"/>
return {
prop1: store.importantCollection
}
},
named1: function(route) {
// <router-view :anotherProp="$store.otherData"/>
return {
anotherProp: store.otherData
}
},
}
Note that this only works if your prop function is scoped so it can see the data you want to pass. The route argument provides no references to the Vue instance, Vuex, or VueRouter. Also, the named1 example demonstrates that this is not bound to any instance either. This appears to be by design, so the state is only defined by the URL. Because of these issues, it could be better to use named views that receive the correct props in the markup and let the router toggle them.
// Router config:
components:
{
default: Component0,
named1: Component1
}
<!-- Markup -->
<router-view name="default" :prop1="$store.importantCollection"/>
<router-view name="named1" :anotherProp="$store.otherData"/>
With this approach, your markup declares the intent of which views are possible and sets them up, but the router decides which ones to activate.
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true }
// for routes with named views, you have to define the props option for each named view:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
Object mode
const router = new VueRouter({
routes: [
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
]
})
That is the official answer.
link
Use:
this.$route.MY_PROP
to get a route prop