监听子组件事件
父级组件可以像处理 native DOM 事件一样通过v-on
监听子组件实例的任意事件,同时子组件可以通过调用内建的$emit
方法并传入事件名称来触发一个事件。
使用事件抛出一个值
可以使用$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
的自定义输入组件。记住:
<input v-model="searchText">
等价于:
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
当用在组件上时,v-model
则会这样:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
为了让它正常工作,这个组件内的<input>
必须:
- 将其
value
attribute 绑定到一个名叫value
的 prop 上 - 在其
input
事件被触发时,将新的值通过自定义的input
事件抛出
写成代码之后是这样的:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
现在v-model
就应该可以在这个组件上完美地工作起来了:
<custom-input v-model="searchText"></custom-input>
通过插槽分发内容
和 HTML 元素一样,我们经常需要向一个组件传递内容,Vue 自定义的<slot>
元素让这变得非常简单。我们只要在需要的地方加入插槽就行了。
动态组件
在不同组件之间进行动态切换是非常有用的,可以通过 Vue 的<component>
元素加一个特殊的is
attribute 来实现。
这个 attribute 可以用于常规 HTML 元素,但这些元素将被视为组件,这意味着所有的 attribute都会作为 DOM attribute 被绑定。对于像value
这样的 property,若想让其如预期般工作,你需要使用.prop
修饰器。
解析 DOM 模板时的注意事项
有些 HTML 元素,诸如<ul>
、<ol>
、<table>
和<select>
,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如<li>
、<tr>
和<option>
,只能出现在其它某些特定的元素内部。
这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:
<table>
<blog-post-row></blog-post-row>
</table>
这个自定义组件<blog-post-row>
会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的is
attribute 给了我们一个变通的办法:
<table>
<tr is="blog-post-row"></tr>
</table>
需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:
- 字符串 (例如:
template: '...'
) - 单文件组件 (
.vue
) <script type="text/x-template">