了解 VueJS 中的组件道具

Understanding component props in VueJS

我正在通过关注 laracasts 系列网络广播来试用 vuejs。在 https://laracasts.com/series/learning-vue-step-by-step/episodes/8 中,Jeffery Way 讨论了自定义组件。我有以下基于他的截屏的代码:

    <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 component instance has its own isolated scope. This means you cannot (and should not) directly reference parent data in a child component’s template. Data can be passed down to child components using props.A “prop” is a field on a component’s data that is expected to be passed down from its parent component. A child component needs to explicitly declare the props it expects to receive using the props option:

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

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

让我们看看这个。首先,您将主 Vue 实例附加(安装)到标识符为 #app 的元素。所以这是你的起点。

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

在您的 div 中,您有一个 <tasks> 标签。该标签对应一个子组件,所以

child = component and parent = the vue instance

正确。 <tasks> 组件是 Vue class 的扩展,它只有一个 属性 声明为 list。这里重要的是作用域。请注意 list 属性 属于任务组件,在其声明中没有值,并且在模板上传递给它的值(#app div 中的所有内容) 属于父 Vue 实例(在 Vue 实例的 data 上声明)。那为什么不props:['tasks']呢? 因为<tasks>组件没有tasks数据或属性。如果您实际上声明了 属性 之类的任务,则必须按如下方式编写模板

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

这会有点令人困惑。这就是为什么道具是 list 并且由于声明 list="tasks" 是组件知道列表 属性 具有父任务数组的值。

现在 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}
        ]

    }