Is it possible to bind query values to props declaratively?
I want /my-foo?bar=my-bar
to pass the props {foo: "my-foo", bar: "my-bar"}
.
I'm currently using something like this:
export default new Router({
routes: [
{
path: "/:foo",
name: "Foo",
component: FooPage,
props: route => ({ foo: route.params.foo, bar: route.query.bar})
}
]
});
And I'm looking for something like:
export default new Router({
routes: [
{
path: "/:foo?bar=:bar",
name: "Foo",
component: FooPage,
props: true
}
]
});
I'm using vue-router 2.3.1
Another way to access the router props is to add an import statement at the top of the component and import 'withRouter'. import { withRouter } from 'react-router-dom'; Then in the export default statement at the end of the component you would wrap the component in 'withRouter'. export default withRouter(HomePage);
To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.
Using props in VueAfter you have set up the props, you can then use it inside your component as though the data was defined inside the same component. This means you can set up method calls and easily access this.
I don't understand the problem with your current approach; solves your use case just fine.
That said, you could try Object.assign
, something like this:
export default new Router({
routes: [{
path: "/:foo?bar=:bar",
name: "Foo",
component: FooPage,
props: route => Object.assign({}, route.query, route.params)
}]
})
... you can also try a more modern approach by using object spread (if you have babel correctly configured) ...
route => ({ ...route.query, ...route.params })
Having route.params
as the last merged/spread item avoids having querystrings overriding path parameters.
I am not aware of any declarative directive for that, but I do like Ricardos general approach. What might be a problem with that is that it unconditionally binds all query parameters as a prop, so one can modify any predefined props of that component just by adding it to the url.
If you want a filter and still reusability, you can define a helper function and bind the query in a less verbose way:
import bindQuery from "./router-query-bind";
export default new Router({
routes: [{
name: "Foo",
path: "/:foo",
props: bindQuery(["bar"]), // only binds 'bar' from query as a prop
component: FooPage
}, {
name: "Bar",
path: "/:bar",
props: bindQuery(), // binds all query parameters as a props
component: BarPage
}]
});
With an implementation like the following. Note that this is TypeScript and has type annotations. Just remove them if you need plain JavaScript.
import { Route } from "vue-router";
type RoutePropsFunction = (route: Route) => Object;
/**
* Creates a props-function for Vue-Router to pass all route parameters and query parameters as
* props to the routed component.
* You may filter the passed query parameters by name so that only the expected
* props will be bound.
* @param queryFilter List of query parameters which will be passed as props to the component.
* This is optional. If not set all query parameters will be bound.
*/
export default function (queryFilter?: string[]): RoutePropsFunction {
return function (route: Route) {
const filtered = queryFilter ?
queryFilter.reduce((a, b) => ({ ...a, [b]: route.query[b] }), {}) :
route.query;
return { ...route.params, ...filtered };
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With