-
-
Notifications
You must be signed in to change notification settings - Fork 5k
New feature: Passing props to components from vue-router #973
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
be7a138
Let the selenium-server and chromedriver packages determine the paths
bfanger 5ad9d48
Feature: routeConfig.props - Passing props to a component
bfanger 0902926
inlined hasProp + cached the regex literal
bfanger 608f6e3
Simplied the { props:true } behaviour which is now very predicable.
bfanger 5ff882e
Updated docs
bfanger a7cd827
Merge branch 'dev' into dev
posva 0ac46ca
Updated docs + re-enabled props functionality
bfanger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Passing props | ||
|
||
Using `$route` in your component creates a tight coupling with the route which limits the flexibility of the component as it can only be used on certain urls. | ||
|
||
To decouple this component from the router use props: | ||
|
||
**❌ Coupled to $route** | ||
|
||
``` js | ||
const User = { | ||
template: '<div>User {{ $route.params.id }}</div>' | ||
} | ||
const router = new VueRouter({ | ||
routes: [ | ||
{ path: '/user/:id', component: User } | ||
] | ||
}) | ||
``` | ||
|
||
**👍 Decoupled with props** | ||
|
||
``` js | ||
const User = { | ||
props: ['id'], | ||
template: '<div>User {{ id }}</div>' | ||
} | ||
const router = new VueRouter({ | ||
routes: [ | ||
{ path: '/user/:id', component: User, props: true } | ||
] | ||
}) | ||
``` | ||
|
||
This allows you to use the component anywhere, which makes the component easier to reuse and test. | ||
|
||
### Boolean mode | ||
|
||
When props is set to true, the route.params will be set as the component props. | ||
|
||
### Object mode | ||
|
||
When props is an object, this will be set as the component props as-is. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be even better to say when it's useful to pass an object as the props There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've improved the description and code snippet. |
||
Useful for when the props are static. | ||
|
||
``` js | ||
const router = new VueRouter({ | ||
routes: [ | ||
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } | ||
] | ||
}) | ||
``` | ||
|
||
### Function mode | ||
|
||
You can create a function that returns props. | ||
This allows you to to cast the parameter to another type, combine static values with route-based values, etc. | ||
|
||
``` js | ||
const router = new VueRouter({ | ||
routes: [ | ||
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) } | ||
] | ||
}) | ||
``` | ||
|
||
The url: `/search?q=vue` would pass `{query: "vue"}` as props to the SearchUser component. | ||
|
||
Try to keep the props function stateless, as it's only evaluated on route changes. | ||
Use a wrapper component if you need state to define the props, that way vue can react to state changes. | ||
|
||
|
||
For advanced usage, checkout the [example](https://github.com/vuejs/vue-router/blob/dev/examples/route-props/app.js). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<template> | ||
<div> | ||
<h2 class="hello">Hello {{name}}</h2> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
|
||
export default { | ||
props: { | ||
name: { | ||
type: String, | ||
default: 'Vue!' | ||
} | ||
} | ||
} | ||
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import Vue from 'vue' | ||
import VueRouter from 'vue-router' | ||
import Hello from './Hello.vue' | ||
|
||
Vue.use(VueRouter) | ||
|
||
function dynamicPropsFn (route) { | ||
const now = new Date() | ||
return { | ||
name: (now.getFullYear() + parseInt(route.params.years)) + '!' | ||
} | ||
} | ||
|
||
const router = new VueRouter({ | ||
mode: 'history', | ||
base: __dirname, | ||
routes: [ | ||
{ path: '/', component: Hello }, // No props, no nothing | ||
{ path: '/hello/:name', component: Hello, props: true }, // Pass route.params to props | ||
{ path: '/static', component: Hello, props: { name: 'world' }}, // static values | ||
{ path: '/dynamic/:years', component: Hello, props: dynamicPropsFn } // custom logic for mapping between route and props | ||
] | ||
}) | ||
|
||
new Vue({ | ||
router, | ||
template: ` | ||
<div id="app"> | ||
<h1>Route props</h1> | ||
<ul> | ||
<li><router-link to="/">/</router-link></li> | ||
<li><router-link to="/hello/you">/hello/you</router-link></li> | ||
<li><router-link to="/static">/static</router-link></li> | ||
<li><router-link to="/dynamic/1">/dynamic/1</router-link></li> | ||
</ul> | ||
<router-view class="view"></router-view> | ||
</div> | ||
` | ||
}).$mount('#app') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<!DOCTYPE html> | ||
<link rel="stylesheet" href="/global.css"> | ||
<a href="/">← Examples index</a> | ||
<div id="app"></div> | ||
<script src="/__build__/shared.js"></script> | ||
<script src="/__build__/route-props.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
import { warn } from './warn' | ||
|
||
export function resolveProps (route, component, config) { | ||
switch (typeof config) { | ||
|
||
case 'undefined': | ||
return | ||
|
||
case 'object': | ||
return config | ||
|
||
case 'function': | ||
return config(route) | ||
|
||
case 'boolean': | ||
if (!config) { | ||
return | ||
} | ||
return route.params | ||
|
||
default: | ||
warn(false, `props in "${route.path}" is a ${typeof config}, expecting an object, function or boolean.`) | ||
} | ||
} | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module.exports = { | ||
'route-props': function (browser) { | ||
browser | ||
.url('http://localhost:8080/route-props/') | ||
.waitForElementVisible('#app', 1000) | ||
.assert.count('li a', 4) | ||
|
||
.assert.urlEquals('http://localhost:8080/route-props/') | ||
.assert.containsText('.hello', 'Hello Vue!') | ||
|
||
.click('li:nth-child(2) a') | ||
.assert.urlEquals('http://localhost:8080/route-props/hello/you') | ||
.assert.containsText('.hello', 'Hello you') | ||
|
||
.click('li:nth-child(3) a') | ||
.assert.urlEquals('http://localhost:8080/route-props/static') | ||
.assert.containsText('.hello', 'Hello world') | ||
|
||
.click('li:nth-child(4) a') | ||
.assert.urlEquals('http://localhost:8080/route-props/dynamic/1') | ||
.assert.containsText('.hello', 'Hello ' + ((new Date()).getFullYear() + 1)+ '!') | ||
|
||
.end() | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is
Boolean
|Object
|Function
in passing-props.md