1.定义组件
通过父传子的配置,确实能够完成一定的组件内容的定制,但是只能完成一些简单的定制,如果是复杂的内容,需要进行定制,就需要学习了解插槽。
初始参考代码片段,效果如下图1
<body>
<div id="app">
<modal></modal>
</div>
<script>
// 定义组件
Vue.component('modal', {
template: `
<div class="modal">
<div class="header">
<h3>警告</h3>
</div>
<div class="main">
<p>您确定要退出本系统?</p>
</div>
<div class="footer">
<button>确认</button>
<button>取消</button>
</div>
</div>
`,
})
//vue实例
const vm = new Vue({
el: '#app',
data: {},
})
</script>
</body>
2.使用插槽的目的:可以帮助我们定制组件的内容
slot作用:可以进行内容的分发
简单说就是利用<slot></slot>
在组件内部占用一个或者多个位置,可供组件传入对应的模板代码进去
插槽
1.匿名插槽
只要是没有具体分配的内容,都会给到匿名插槽
<slot></slot>
或者<slot name="default"></slot>
(1)直接在modal
组件中自定义标签内容如<h1>温馨提示:</h1>
,当然此时可以为任意标签任意内容,并且组件可以复用,效果如下图2
<div id="app">
<modal>
<h3>警告:</h3>
</modal>
<modal>
<h1>温馨提示:</h1>
</modal>
</div>
(2)同时在子组件中需替换为<slot></slot>
用于占位,即在modal
组件中自定义的内容都会显示在slot占位的位置
【可以参考上方初始代码对比】
// 定义组件
Vue.component('modal', {
template: `
<div class="modal">
<div class="header">
<slot></slot>
</div>
</div>
`,
})
注意:<slot></slot> 等于 <slot name="default"></slot>
2.具名插槽
指带有名字的插槽,如果组件内需要多个插槽,因此配置了名字的插槽,才可以实现定向分发指定插入.
<slot>
元素有一个特殊的attribute:name
。这个attribute
可以用来定义额外的插槽:
使用步骤:
(1)给插槽起名字<slot name='自定义名字'></slot>
// 定义组件
Vue.component('modal', {
template: `
<div class="modal">
<div class="header">
<slot name="header"></slot>
</div>
<div class="main">
<slot name="main"></slot>
</div>
<div class="footer">
<slot name="default"></slot>
</div>
</div>
`,
})
(2)在分发内容时,通过template
标签,将内容包裹,且里面可以添加任意标签内容,并指定分发的插槽名v-slot:插槽名
。
<div id="app">
<modal>
<template v-slot:header>
<h3>警告:</h3>
</template>
<template v-slot:main>
<p>您确定要退出本系统?</p>
</template>
<template v-slot:default>
<button>确认</button>
<button>取消</button>
</template>
</modal>
</div>
现在<template>
元素中的所有内容都将会被传入 对应的插槽。
任何没有被包裹在带有v-slot
的 <template>
中的内容都会被视为匿名插槽的内容。
总结:
1.具名插槽的内容必须使用模板<template></template>
包裹
2.<slot></slot>
等价于 <slot name="default"></slot>
3.vue >=2.6.0版本,使用v-slot
替代slot 和 slot-scope
4.v-slot:slotName
,slotName
不需要加引号""
5.v-slot:header
可以简写成#header
, v-slot:default
可以简写成#default
作用域插槽
指在定义插槽的同时,不论匿名插槽还是具名插槽是可以传值的。如果子组件中有数据,想要在父模板分发内容的时候使用
通俗讲就是父组件需要用到子组件插槽里面数据的时候,通过v-slot:插槽名='自定义对象名'
来接收子组件插槽的数据
使用步骤:
1.定义插槽的同时,以添加属性的方式传值。例如:给slot
添加属性btnName
等
<slot name="default" btnName1='确认' btnName2='取消'></slot>
2.在传入的template
中就可以获取,slot
传过来的值,可以直接通过=
接收,最终会保存到一个对象中如scope
【scope
只是自定义的一个变量对象名】,然后通过对象取值即v-slot:插槽名='自定义对象名'
<template v-slot:default='scope'>
<button>{{scope.btnName1}}</button>
<button>{{scope.btnName2}}</button>
</template>
当然传值有时候是需要动态获取的如:
1.动态传值
<slot name="default" :yes='yes' :no='no'></slot>
data() {
return {
yes: '确认',
no: '取消'
}
}
同样通过scope
对象接收获取参数
<template v-slot:default="scope">
<button>{{scope.yes}}</button>
<button>{{scope.no}}</button>
</template>