天天看点

vue基础课程学习之组建基础(十二)

#基本示例

vue基础课程学习之组建基础(十二)

组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 <code>&lt;btton-counter&gt;</code>。我们可以在一个通过 <code>new Vue</code> 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:

vue基础课程学习之组建基础(十二)

因为组件是可复用的 Vue 实例,所以它们与 <code>new Vue</code> 接收相同的选项,例如 <code>data</code>、<code>computed</code>、<code>watch</code>、<code>methods</code> 以及生命周期钩子等。仅有的例外是像 <code>el</code> 这样根实例特有的选项。

#组件复用

vue基础课程学习之组建基础(十二)

注意当点击按钮时,每个组件都会各自独立维护它的 <code>count</code>。因为你每用一次组件,就会有一个它的新实例被创建。

vue基础课程学习之组建基础(十二)
vue基础课程学习之组建基础(十二)

例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。至此,我们的组件都只是通过 <code>Vue.component</code> 全局注册的:

vue基础课程学习之组建基础(十二)

全局注册的组件可以用在其被注册之后的任何 (通过 <code>new Vue</code>) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。

#通过prop向子组件传递数据

早些时候,我们提到了创建一个博文组件的事情。问题是如果你不能向这个组件传递某一篇博文的标题或内容之类的我们想展示的数据的话,它是没有办法使用的。这也正是 prop 的由来。

Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。为了给博文组件传递一个标题,我们可以用一个 <code>props</code> 选项将其包含在该组件可接受的 prop 列表中:

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 <code>data</code> 中的值一样。

vue基础课程学习之组建基础(十二)
vue基础课程学习之组建基础(十二)

然而在一个典型的应用中,你可能在 <code>data</code> 里有一个博文的数组:

vue基础课程学习之组建基础(十二)

如上所示,你会发现我们可以使用 <code>v-bind</code> 来动态传递 prop。

代码:

&lt;!DOCTYPE html&gt;

&lt;html&gt;

       &lt;head&gt;

              &lt;meta charset="utf-8"&gt;

              &lt;title&gt;组件基础&lt;/title&gt;

              &lt;script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&gt;&lt;/script&gt;

       &lt;/head&gt;

       &lt;body&gt;

              &lt;div id="app"&gt;

                     &lt;blog-post

                       v-for="post in posts"

                       v-bind:key="post.id"

                       v-bind:title="post.title"

                     &gt;&lt;/blog-post&gt;

              &lt;/div&gt;

       &lt;/body&gt;

       &lt;script type="text/javascript"&gt;

              Vue.component('blog-post', {

                props: ['title'],

                template: '&lt;h3&gt;{{ title }}&lt;/h3&gt;'

              })

              var vm = new Vue({

                     el: '#app',

                       data: {

                         posts: [

                           { id: 1, title: 'My journey with Vue' },

                           { id: 2, title: 'Blogging with Vue' },

                           { id: 3, title: 'Why Vue is so fun' }

                         ]

                       }

       &lt;/script&gt;

&lt;/html&gt;

#单个根元素

vue基础课程学习之组建基础(十二)
vue基础课程学习之组建基础(十二)

       这样写会报错,每个组件必须只有一个根元素。解决办法是将模板的内容包裹在一个父元素内。

vue基础课程学习之组建基础(十二)

当然我们也可以创建单文件组件,&lt;script type="text/x-template"&gt; 这样如果template中添加内容较长,编写与查看都不方便。所以就需要使用自定义单文件组件了。

vue基础课程学习之组建基础(十二)

#监听子组件事件

vue基础课程学习之组建基础(十二)

在我们开发 <code>&lt;blog-post&gt;</code> 组件时,它的一些功能可能要求我们和父级组件进行沟通。例如我们可能会引入一个辅助功能来放大博文的字号,同时让页面的其它部分保持默认的字号。

在其父组件中,我们可以通过添加一个 <code>postFontSize</code> 数据 property 来支持这个功能:

vue基础课程学习之组建基础(十二)

它可以在模板中用来控制所有博文的字号:

vue基础课程学习之组建基础(十二)

现在我们在每篇博文正文之前添加一个按钮来放大字号:

vue基础课程学习之组建基础(十二)

当点击这个按钮时,我们需要告诉父级组件放大所有博文的文本。幸好 Vue 实例提供了一个自定义事件的系统来解决这个问题。父级组件可以像处理 native DOM 事件一样通过 <code>v-on</code> 监听子组件实例的任意事件:

vue基础课程学习之组建基础(十二)

有了这个 <code>v-on:enlarge-text="postFontSize += 0.1"</code> 监听器,父级组件就会接收该事件并更新 <code>postFontSize</code> 的值。

最后是交流公众号,大家可以关注一下

vue基础课程学习之组建基础(十二)