Vue.js知识库(五):自定义事件和插槽
自定义事件、插槽的作用域、具名插槽。
245阅读 · 2020-8-28 23:47发布
自定义事件
事件名称
事件名称可以使用kebab-case(短横线分隔命名)命名,并且需要全部为小写(v-on事件监听器在 DOM 模板中会被自动转换为全小写)。
自定义组件的v-model
子组件里可以通过v-model来向父组件传递值,使父组件的属性更新。
Vue.component('base-checkbox', {
<!--change事件时传递checked给v-model绑定的属性-->
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
<!--下面是通过$emit触发change事件给model-->
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
<!--通过v-model绑定父组件中的lovingVue-->
<base-checkbox v-model="lovingVue"></base-checkbox>
绑定原生事件
根元素上监听原生事件,可以使用v-on
的.native
修饰符。
<base-input v-on:focus.native="onFocus"></base-input>
.sync修饰符
可以通过sync修饰符,使子组件向父组件传递值并修改父组件的值。
this.$emit('update:title', newTitle)
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
//方面的写法和下面相同
<text-document v-bind:title.sync="doc.title"></text-document>
当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用:
<text-document v-bind.sync="doc"></text-document>
插槽
- 插槽使用
元素表示。 - 组件渲染时,会将
替换为子组件元素之间的内容。 - 如果组件中不包含
,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
插槽的作用域
- 插槽中的内容,只允许访问组件内部定义的属性。
- 父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
插槽的默认内容
- 如果
之间有内容,父组件使用子组件时没有在子组件之间增内容。则最终会显示 时间的内容。
// 子组件模板
<button type="submit">
<slot>Submit</slot>
</button>
//父组件中调用
<submit-button></submit-button>
//最终渲染
<button type="submit">
Submit
</button>
具名插槽
- 如果一个页面中包含多个插槽,可以使用name属性给slot添加名称。
- 一个不带name属性的
会隐含名字default。
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
具名插槽的缩写
- 2.6.0 新增。
- 将【v-slot:】替换为字符【#】。
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</base-layout>
- 如果有参数,并且使用缩写,需要使用如下写法。
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
作用域插槽
父级插槽中使用子组件数据
//方法一:绑定属性
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
//方法二:使用插槽prop
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
只有一个插槽时的简单写法
//和v-slot:default="slotProps"含义一样(仅限只有一个插槽时可以使用这种写法)
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>
动态插槽名
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>