插槽的理解
插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签,适用于父组件==>子组件
默认插槽
定义与使用
定义插槽(子组件的模板中定义):其中子组件的插槽中内容也会展示
<slot>子组件插槽中的默认内容</slot>
使用插槽(父组件的模板中使用):
<child>其中的内容全部替换到子组件的插槽中</child>
其余问题
- slot 作用域问题
-
父模版里调用的数据属性,使用的都是父模板里的数据
-
子模版里调用的数据属性,使用的都是子模板里的数据
2. 默认内容设定
-
slot标签中定义插槽的默认内容,若父组件未传递就会使用默认内容
-
父组件传递了插槽内容就不会显示定义在插槽中的默认值
实例可查看下列情况一和情况二
情况分析
情况一:父组件中使用插槽未传递内容,显示子组件中插槽内容
代码如下:
<script>
const app= Vue.createApp({
template:`
<list></list>
`
});
app.component('list',{
data() {
return {list:[1,2,3]}},
template:`
<div>
<slot>{{list}}子组件插槽中的默认内容</slot>
</div>
`
})
const vm = app.mount('#root');
</script>
实现效果:
情况二:父组件中使用插槽有传递内容,显示父组件模板中子组件标签中的内容
代码如下:
<script>
const app= Vue.createApp({
template:`
<child>
<h2>父组件</h2>
<input value='父组件内容' />
</child>
`
});
app.component('child',{
data() {
return {list:[1,2,3]}
},
template:`
<div>
<slot>{{list}}子组件插槽中的默认内容</slot>
</div>
`
})
const vm = app.mount('#root');
</script>
实现效果:
情况三:
代码如下:
<script>
const app= Vue.createApp({
data() {
return {
text:'提交'
}
},
template:`
<myform>
<div>{{text}}</div>
</myform>
<myform>
<button>{{text}}</button>
</myform>
`
});
app.component("myform",{
methods: {
handleClick(){
alert(123)
}
},
template:`
<div>
<input />
<span @click="handleClick">
<slot> </slot>
</span>
</div>
`
})
const vm = app.mount('#root');
</script>
实现效果:
具名插槽
实现插槽多个标签用在不同位置,即一个子组件多用
定义与使用
定义插槽(子组件的模板中定义):
<slot :name:"name">子组件插槽中的默认内容</slot>
使用插槽(父组件的模板中使用):
<child>
<template v-slot:name> <div>{{message}}</div> </template>
</child>
//可简写为
<child>
<template #name> <div>{{message}}</div> </template>
</child>
注意:默认插槽的name=‘default’
情况分析
- 使用template标签包裹并使用v-slot:xxx来进行标识写在template中,可简写为**#xxx**
- 在子组件中的slot标签里并配置name="xxx" 来接收父组件传递过来的
<script>
const app= Vue.createApp({
template:`
<layout>
<template #header>
<div>header</div>
</template>
<template #footer>
<div>footer</div>
</template>
</layout>
`
});
app.component('layout',{
template:`
<div>
<slot name="header"></slot>
<div>content</div>
<slot name="footer">
</div>
`
})
const vm = app.mount('#root');
</script>
运行结果:
作用域插槽
Vue 官方文档中说明:父模版里调用的数据属性,使用的都是父模板里的数据;子模版里调用的数据属性,使用的都是子模板里的数据。
作用域插槽就是让子组件中的数据在父级的插槽内容,数据不在父组件身上,而是在子组件身上,且组件的结构和内容由父组件决定。
- 父组件调子组件时传递标签替换slot,子组件的插槽中通过:xx="xx"(属性的形式)将数据传给父组件
- 父组件通过v-slot="obj"接收数据,传递来的值保存在obj对象里中,之后即可使用该对象中的属性进行{{}}显示操作
代码如下:
<script>
const app= Vue.createApp({
template:`
<list v-slot="{{item}}">
<div>{{item}}</div>
</list>
`
});
app.component('list',{
data() {
return {list:[1,2,3]}},
template:`
<div>
<slot v-for="item in list" :item="item"></slot>
</div>
`
})
const vm = app.mount('#root');
</script>
实现效果: