2016-01-13 85 views
7

我正在尝试vuejs跟随laracasts系列的网络广播。 Jeffrey Way在https://laracasts.com/series/learning-vue-step-by-step/episodes/8中讨论了自定义组件。我根据他的截屏下面的代码:了解VueJS中的组件道具

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

    <template id="tasks-template"> 
     <ul> 
      <li :class="{'completed' : task.c}" @click = "task.c = ! task.c" v-for ="task in tasks">{{task.t}}</li> 

     </ul> 

    </template> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.12/vue.js"></script> 
    <script type="text/javascript"> 

    vue.component('tasks', { 
    template: '#tasks-template', 

    props:['list'] // why not props:['tasks'] ?? 

    }); 

    new Vue({ 
    el: '#app', 
    data: { 
     tasks: [ 
      {t: 'go to doctor', c: false}, 
      {t: 'go to work', c: false}, 
      {t: 'go to store', c: true} 
     ] 

    } 

在此,他讨论了设定道具如下:

props:['list'] 

为什么不

props:['tasks'] ? 

http://vuejs.org/guide/components.html#Props它指出:

Every comp onent实例有其自己的隔离范围。这意味着您不能(也不应该)直接引用子组件模板中的父数据。可以使用props将数据传递给子组件。“prop”是组件数据上的字段,预计将从其父组件传递。子组件需要使用道具选项明确声明它期望收到的道具:

组件如何知道将任务数组与列表关联?在这种情况下,我假设child = component和parent = vue实例?

回答

7

组件上的属性名为list,传递给它的值为tasks

让我们来看看这个。首先,您的主Vue实例附带了(已装载)到标识为#app的元素。所以这是你的出发点。

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

你的div里面有一个<tasks>标签。该标签对应一个子组件,所以

孩子=组分和家长=的VUE实例

是正确的。 <tasks>组件是Vue类的扩展,只有一个属性被声明为list。这里重要的是范围。请注意,list属性属于任务组件,并且在其声明中没有值,并且在模板上传递给它的值(#app div内的所有内容)都属于父Vue实例(在Vue实例的data上声明) )。那么为什么不props:['tasks']因为<tasks>组件没有tasks数据或属性。如果你真的喜欢宣告任务的属性,你会写你的模板如下

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

这将是一个利特尔混乱。所以这就是为什么道具是list,并且因为声明list="tasks"是组件知道列表属性具有父任务数组的值。

+0

数据是如何:任务[]成为从视图实例阵列可用于绑定列表=“任务”?我的猜测是,在阅读你所写的内容之后,它在视图实例元素的范围内变得可用 - 即

user61629

+0

'#app' div中的所有内容都可以从主Vue实例中获得。会发生什么情况是,主vue实例可以访问组件和组件,因为每个vue实例总是暴露他们'data'和'props'内部的内容。因此,'list'属性属于组件,但可通过组件 –

+1

与主实例联系。感谢您的帮助! – user61629

3

现在发布Vuejs 2.x。您可以使用v-bind动态绑定道具。您也可以参考https://vuejs.org/v2/guide/components.html#Dynamic-Props

您需要注意的一件事是HTML属性不区分大小写,所以当使用非字符串模板时,camelCased prop名称需要使用它们的kebab-case(连字符分隔)当量。例如

Vue.component('child', { 
 
    // camelCase in JavaScript 
 
    props: ['myMessage'], 
 
    template: '<span>{{ myMessage }}</span>' 
 
})
<!-- kebab-case in HTML --> 
 
<child my-message="hello!"></child>

所以你的样品可以换到下面

<div id="app"> 
 
     <tasks v-bind:list="tasks"></tasks> 
 
    </div> 
 

 
    <template id="tasks-template"> 
 
     <ul> 
 
      <li :class="{'completed' : task.c}" @click = "task.c = ! task.c" v-for ="task in tasks">{{task.t}}</li> 
 

 
     </ul> 
 

 
    </template> 
 

 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script> 
 
    <script type="text/javascript"> 
 

 
    vue.component('tasks', { 
 
    template: '#tasks-template', 
 

 
    props:['list'] // why not props:['tasks'] ?? 
 

 
    }); 
 

 
    new Vue({ 
 
    el: '#app', 
 
    data: { 
 
     tasks: [ 
 
      {t: 'go to doctor', c: false}, 
 
      {t: 'go to work', c: false}, 
 
      {t: 'go to store', c: true} 
 
     ] 
 

 
    }