组件基础
实例
这里有一个 Vue 组件的示例:
// 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) |
组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 <button-counter>
。我们可以在一个通过 new Vue
创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
<div id="components-demo"> <button-counter></button-counter> </div> |
new Vue({ el: '#components-demo' }) |
注意:
data
必须是一个函数:
一个组件的 data
选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () { return { count: 0 } } |
如果 Vue 没有这条规则,点击一个按钮就可能会像如下一样影响到其它所有实例
通过 Prop 向子组件传递数据
我们可以用props 来 从父级向子级传递信息
Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>' })
<blog-post title="My journey with Vue"></blog-post> <blog-post title="Blogging with Vue"></blog-post> <blog-post title="Why Vue is so fun"></blog-post>
单个根元素
每个组件必须只有一个根元素) 。你可以将模板的内容包裹在一个父元素内,来修复这个问题通过事件向父级组件发送消息
我们可以调用内建的 $emit
方法并传入事件的名字,来向父级组件触发一个事件:
<button v-on:click="$emit('yc')"> Enlarge text </button> |
然后我们可以用 v-on
在博文组件上监听这个事件,就像监听一个原生 DOM 事件一样:
<blog-post ... v-on:yc="postFontSize += 0.1" ></blog-post> |
使用事件抛出一个值
有的时候用一个事件来抛出一个特定的值是非常有用的。例如我们可能想让 <blog-post>
组件决定它的文本要放大多少。这时可以使用 $emit
的第二个参数来提供这个值:
<button v-on:click="$emit('enlarge-text', 0.1)"> Enlarge text </button> |
然后当在父级组件监听这个事件的时候,我们可以通过 $event
访问到被抛出的这个值:
<blog-post ... v-on:enlarge-text="postFontSize += $event" ></blog-post> |
或者,如果这个事件处理函数是一个方法:
<blog-post ... v-on:enlarge-text="onEnlargeText" ></blog-post> |
那么这个值将会作为第一个参数传入这个方法:
methods: { onEnlargeText: function (enlargeAmount) { this.postFontSize += enlargeAmount } } |
在组件上使用 v-model
自定义事件也可以用于创建支持 v-model
的自定义输入组件。
Vue.component('custom-input', { props: ['value'], template: ` <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > ` })
<custom-input v-model="searchText"></custom-input>
通过插槽分发内容
和 HTML 元素一样,我们经常需要向一个组件传递内容,像这样:
<alert-box> Something bad happened. </alert-box> |
Vue 自定义的 <slot>
元素让这变得非常简单:
Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error!</strong> <slot></slot> </div> ` }) |
如你所见,我们只要在需要的地方加入插槽就行了——就这么简单!