2017-05-04 32 views
1

当我所有的道具传承给孩子以这种方式Vuejs自动传下来的所有道具子

v-bind="$props" 

父传下所有的道具,但孩子不过滤它,如果不承认在我们的html中支持子打印。 结果是脏的和无效的HTML :(

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

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

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

为u在这个例子中看到组件BB有这个HTML

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

和成分CC具有

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

这是一个很大的公关当我有很多道具

我知道我可以解决它只传递组件需要的道具,但对于一个大型应用程序,我需要搜索我所有的组件,并且每次添加一个新的道具时需要添加它。这是有问题的... 在previus版本(2.1.10),它完美的作品!

+0

那么,如果你撑起流动变得复杂,你应该cosider关于引入Vuex到您的应用程序,并保持所有数据存储。 –

+0

是的,正如@BelminBedak所说,vuex是个好主意。此外,Vue使所有范围和imho有点不舒服,将其传递给儿童/父母,以便您的组件尽可能独立。其实这或多或少是vue的目的,所以我们不应该试图破解它;) –

回答

2

快速规格的道具降低了代码的清晰度,所以你应该避免这样做。子道具名称与父项道具名称匹配的情况表明您应该使用event bus或(根据评论者的建议)使用Vuex数据存储。

尽管如此,可以反思组件的道具,因此只能绑定组件需要的组件。

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: ` 
 
\t \t \t <div>here is cc 
 
\t \t \t \t {{y}} 
 
\t \t \t </div> 
 
\t \t `, 
 
    props: ['y'] 
 
}); 
 
Vue.component('bb', { 
 
    template: ` 
 
\t \t \t <div>here is bb 
 
\t \t \t \t {{x}} 
 
\t \t \t </div> 
 
\t \t `, 
 
    props: ['x'] 
 
}); 
 

 
Vue.component('aa', { 
 
    template: ` 
 
\t \t \t <div>here is aa 
 
\t \t \t \t <bb v-bind="propsFor('bb', $props)" :x="'1'"/> 
 
     <cc v-bind="propsFor('cc', $props)" /> 
 
\t \t \t </div> 
 
\t \t `, 
 
    props: ['x', 'y'] 
 
}) 
 
var a = new Vue({ 
 
    template: ` 
 
\t \t <div> 
 
\t \t \t <aa :x="x" :y="1"/> 
 
\t \t </div> 
 
\t \t `, 
 
    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>