-
-
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
Conversation
Makes it easier to upgrade to those packages.
Interesting idea! |
} | ||
|
||
function hasProp (component, prop) { | ||
if (!component.props) { |
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.
Can probably skip this if (!component.props)
check since it's already done in https://github.com/bfanger/vue-router/blob/5ad9d480eeed6700a26597484d0c0454d30a13e3/src/util/props.js#L20-L22
Or maybe just inline this function and use the typof
expression..
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.
Agreed, i've inlined the hasProp function
const propType = component.props[prop].type | ||
if (propType === null || propType === String) { | ||
props[prop] = value | ||
} else if (propType === Number && value.match(/^-?([0-9]+|[0-9]*\.[0-9]+)$/)) { |
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.
Should probably cache this regex literal /^-?([0-9]+|[0-9]*\.[0-9]+)$/
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.
Agreed, done
@@ -49,6 +51,7 @@ export default { | |||
matched.instances[name] = undefined | |||
} | |||
} | |||
data.props = resolveProps(route, component, matched.props && matched.props[name]) |
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.
Should merge with the original data.props
, or it would be a breaking change as the current code disallows explicitly passing props to <router-view>
, like <router-view foo="bar"/>
Edit: Sorry, I was wrong about that..
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.
The props of <router-view>
are still passed to the rendered element. The <div>
in Hello still gets the class="view"
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.
Did some further testing and setting properties on <router-view>
overwrites the values set in data.props, so they are merged somewhere
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.
Yep, that's normal Vue behaviour for any component.
for (const prop in route.params) { | ||
const value = route.params[prop] | ||
if (hasProp(component, prop)) { | ||
const propType = component.props[prop].type |
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.
I'm not sure about reading prop types at runtime and converting them to Number
if possible.. Maybe we should just leave them as string since url params are string by nature. And if Number
was supported, should we also support Boolean
?
Also, if this type conversion were to be supported, type
can be an array, so we'll have to loop over that should it be the case.
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.
Not ideal, but the alternative was either not to support Number type, or pass it as an string and get a propType warnings and subtle bugs in itemsById.find(item => item.id === id)
I think routing to ID is a common use-case to allow it in the {props: true} scenario
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.
Maybe in that case, the user should provide a function and convert types by himself. This way we avoid the implicit behavior.
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.
I've simplified the behavior of the {props: true} which now sets the props to route.params.
Vue complaining about type is much better than silently ignoring some properties and leaving users confused why it doesn't work.
I love the idea! |
I think this is a really great idea. /ping @yyx990803 you should check this out, seems very useful! |
Looks good! Will review in depth after new year and likely merge when we work on 2.2 for the router. |
@@ -1,4 +1,7 @@ | |||
// http://nightwatchjs.org/guide#settings-file | |||
var seleniumServer = require('selenium-server'); | |||
var chromedriver = require('chromedriver'); |
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.
This line is not necessary
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.
lines are removed
@@ -7,7 +10,7 @@ module.exports = { | |||
|
|||
'selenium': { | |||
'start_process': true, | |||
'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar', | |||
'server_path': seleniumServer.path, |
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.
To be consistent we should do server_path': require('selenium-server').path
instead
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.
done
|
||
### 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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
I've improved the description and code snippet.
@bfanger apologies for taking so long to merge this - great work! |
@@ -13,6 +13,7 @@ | |||
name?: string; // for named routes | |||
components?: { [name: string]: Component }; // for named views | |||
redirect?: string | Location | Function; | |||
props?: boolean | string | Function; |
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
Decouple component from the router by using props:
Documentation: https://github.com/bfanger/vue-router/blob/dev/docs/en/essentials/passing-props.md
Examples: https://github.com/bfanger/vue-router/tree/dev/examples/route-props