理解 VueJS 中的组件 props

Posted

技术标签:

【中文标题】理解 VueJS 中的组件 props【英文标题】:Understanding component props in VueJS 【发布时间】:2016-04-18 18:40:06 【问题描述】:

我正在尝试 vuejs,并跟随 laracasts 系列的网络广播。在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 中声明:

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

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

【问题讨论】:

【参考方案1】:

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

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

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

在您的 div 中,您有一个 &lt;tasks&gt; 标记。该标签对应一个子组件,所以

child = 组件和 parent = vue 实例

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

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

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

【讨论】:

视图实例中的 data:tasks[] 数组如何绑定到 list="tasks" ?我的猜测,在阅读了您所写的内容后,它在视图实例元素的范围内变得可用 - 即 #app div 中的所有内容都可以从主 Vue 实例中获得。发生的情况是主 vue 实例可以访问组件和组件,因为每个 vue 实例总是暴露其内部的内容 dataprops。所以,list 属性属于组件,但可以通过组件访问到主实例 感谢您的帮助!【参考方案2】:

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

需要注意的一点是 HTML 属性不区分大小写,因此在使用非字符串模板时,camelCased 的道具名称需要使用它们的 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
        ]

    

【讨论】:

以上是关于理解 VueJS 中的组件 props的主要内容,如果未能解决你的问题,请参考以下文章

vuejs之选项-数据 的笔记与理解

VueJS 中的 props 相互依赖

当从 vuejs 组件中的 props 解码回来时,Vuejs 改变了 json_encoded 数组的顺序

避免 vueJS 中的 props 突变

React Props 原理理解

React Props 原理理解