Vue: Feature: Use spread operator to pass down props.

Created on 17 Feb 2017  Â·  11Comments  Â·  Source: vuejs/vue

Hello,

I propose adding a feature that allows the use of ES6 spread operator to destructure an object into props passed into a component. This feature idea comes from the use of it in react, which is documented here. https://facebook.github.io/react/docs/jsx-in-depth.html#spread-attributes

Imagine an ActorCard that displays a users firstName, lastName, email and imageUrl picture.

Currently

<ActorCard 
  :firstName="currentUser.firstName"
  :lastName="currentUser.lastName"
  :email="currentUser.email"
  :imageUrl="currentUser.imageUrl"
>
</ActorCard>

//or by passing object
<ActorCard :user="currentUser"></ActorCard>

Using spread would allow to pass flat props to the component without all the boiler plate of manually specifying each prop.

<ActorCard {{...currentUser}}></ActorCard>

would compile into the first example above

Doing this way encourages keeping props flat, which ultimately makes components more reusable (i.e. i don't have to construct an object that has property of firstName and lastName just to reuse this actor card if i go the easy route and just pass in a user.)

If this is something that is agreeable, i'm happy and willing to put in the work to get a PR for it.

Thanks!
Austin

Most helpful comment

You can already do this with v-bind="currentUser".

All 11 comments

You can already do this with v-bind="currentUser".

Awesome, thanks!

Can you use .sync this way?

Ends up the answer is yes!

the v-bind="currentUser" works for props / data binding.

And is there a way to pass down event binding / directive props
like

<custom-comp
  :subProps="{ 
      prop1: 1, prop2: 2, 
      'v-on:click': function($e){ console.log($e) },
      'v-custom-directive': true
   }"
/>

custom-comp definition

<template>
<div class='custom-comp'>
  <input
    type='text'
    name='name'
    v-bind='subProps'
  />
</div>
</template>

but the v-on:click & v-custom-directive will not work, only results

<input data-v-2a851830="" type="text" name="name" prop1="1" prop2="2" v-on:click="function($e) {
          _vm.console.log($e)
        }" v-custom-directive="true">

the directive is rendered as attributes but not directives

@magicdawn Have you found a solution to your example? This is a very common pattern I would say, but it seems quite tricky to accomplish (a lot of custom handling in a render method).

@esbenam not yet with templates

if you are tired of writing render function, you can try vue jsx
https://github.com/vuejs/babel-plugin-transform-vue-jsx#difference-from-react-jsx

it supports object spread pattern and express vue terminologies (e.g directives / events) in a prop way

@magicdawn yeah, that is what I have ended up doing for now.

Just got the same problem using v-bind, props are rended to attributes, not directives.
Seems jsx will work.

hello , 尤大 。 how to use sync ?
currentOptions: { val: 0, min: 0, max: 2048 ,dynamicMax: 500, dynamicMin: null } <ActorCard v-bind="currentOptions" :val.sync= currentOptions.val />
@yyx990803

@caokunyu you can ask questions on the forum, the Discord server or StackOverflow

don't do it on issues please 😛
You might be looking for this: https://cn.vuejs.org/v2/guide/components-custom-events.html#sync-%E4%BF%AE%E9%A5%B0%E7%AC%A6 or https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gkiely picture gkiely  Â·  3Comments

robertleeplummerjr picture robertleeplummerjr  Â·  3Comments

hiendv picture hiendv  Â·  3Comments

paulpflug picture paulpflug  Â·  3Comments

lmnsg picture lmnsg  Â·  3Comments