1

When I passing down all prop to child in this way

v-bind="$props"

The parent pass down all props but the child doesn't filter it and if doesn't recognise the props the child print in our html. The result is a dirty and invalid html :(

 Vue.component('cc', {
  template: `
   <div>here is cc
    {{y}}
   </div>
  `,
  props: ['y']
 }); 
  Vue.component('bb', {
  template: `
   <div>here is bb
    {{x}}
   </div>
  `,
  props: ['x']
 });

 Vue.component('aa', {
  template: `
   <div>here is aa
    <bb v-bind="$props" :x="'1'"/>
        <cc v-bind="$props" />
   </div>
  `,
  props: ['x', 'y']
 })
 var a = new Vue({
  template: `
  <div>
   <aa :x="x" :y="1"/>
  </div>
  `,
  data(){
   return {
    x: 0
   };
  }
 });
 a.$mount('#app');
<script src="https://unpkg.com/vue"></script>

<div id="app">
</div>

As u see in this example the component bb have this HTML

<div y="1">here is bb 1</div>

and the component cc have

<div x="0">here is cc 1</div>

it's a big problem when I've a lot of props

I know that I can resolve it passing down only the prop that the component need, but with a large app I need to search all my components and add a new prop every time I need to add it. It's so problematic... In the previus version (2.1.10) it works perfectly!

Stefano
  • 390
  • 3
  • 10
  • Well if you prop flow becomes complex, you should cosider about introducing Vuex into the your app and keep all data in store. – Belmin Bedak May 04 '17 at 09:08
  • Yeah, as @BelminBedak said, vuex is great idea. Also Vue makes everything scoped and imho kinda uncomfortable to pass it to children/parents so your components are as independent as possible. Actually it's more or less purpose of vue so we should not try to hack it ;) – Dominik Dosoudil May 04 '17 at 10:28

1 Answers1

2

Shortcutting the specification of props reduces the clarity of your code, so you should incline away from doing it. The situation of the child props names matching the parent props names suggests that you should be using an event bus or (as commenters suggested) Vuex data store.

Nevertheless, it is possible to introspect the component props and so only bind the ones the component requires.

function propsFor(componentName, propSource) {
  const P = Vue.component(componentName).prototype;
  const propNames = Object.keys(P);
  // More expensively, but more correctly:
  // propNames = Object.keys(new (Vue.component(componentName))().$props);
  const result = {};

  for (const n of propNames) {
    result[n] = propSource[n];
  }
  return result;
}

Vue.component('cc', {
  template: `
   <div>here is cc
    {{y}}
   </div>
  `,
  props: ['y']
});
Vue.component('bb', {
  template: `
   <div>here is bb
    {{x}}
   </div>
  `,
  props: ['x']
});

Vue.component('aa', {
  template: `
   <div>here is aa
    <bb v-bind="propsFor('bb', $props)" :x="'1'"/>
        <cc v-bind="propsFor('cc', $props)" />
   </div>
  `,
  props: ['x', 'y']
})
var a = new Vue({
  template: `
  <div>
   <aa :x="x" :y="1"/>
  </div>
  `,
  data() {
    return {
      x: 0
    };
  }
});
a.$mount('#app');
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.2/vue.min.js"></script>
<div id="app">
</div>
Community
  • 1
  • 1
Roy J
  • 42,522
  • 10
  • 78
  • 102