Bind query to props with vue-router

2019-06-16 07:41发布

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

2条回答
劳资没心,怎么记你
2楼-- · 2019-06-16 08:23

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.params, route.query)
  }]
})

... you can also try a more modern approach by using object spread (if you have babel correctly configured) ...

route => ({ ...route.params, ...route.query })
查看更多
爷的心禁止访问
3楼-- · 2019-06-16 08:36

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 };
    }
}
查看更多
登录 后发表回答