当前位置: 代码迷 >> 综合 >> 【vue】slot
  详细解决方案

【vue】slot

热度:69   发布时间:2023-12-16 18:42:32.0

文章目录

        • 默认slot
        • 具名slot
        • 作用域slot
        • 作用域slot应用于组件复用

默认slot
<body><div id="root"><save-button></save-button></div>
</body>
import Vue from "vue";Vue.component("submit-button",{
    template:'<div>\<button>\<slot>Submit</slot>\</button>\</div>'
});
Vue.component("save-button",{
    template:'<submit-button>Save</submit-button>'
})
// Vue.component("save-button",{
    
// template:'<submit-button></submit-button>'
// })
const vm = new Vue({
    el:"#root"
});

在这里插入图片描述

具名slot
  • H5新元素
    • header
    • nav
    • article
    • section
    • aside
    • footer
<body><div id="root"><header>here is header</header><nav>here is nav</nav><div><article><section>here is article &gt; section</section></article><aside>here is aside</aside></div><footer>here is footer</footer></div>
</body>

在这里插入图片描述

  • 具名slot
    • <template v-slot:对应的slot名称> </template>
    • <slot name="slot名称"></slot>
    • <template v-slot=""></template>的子内容将插入到<slot name=""><slot>所在位置
<body><div id="root"><base-layout><template v-slot:header><h4>here is header</h4></template><template v-slot:default><p>here is the section</p><p>here is the content of the section</p></template><template v-slot:footer><p>here is footer</p></template></base-layout></div>
</body>
import Vue from "vue";Vue.component("base-layout",{
    template:'<div class="container">\<header>\<slot name="header"></slot>\</header>\<section>\<slot name="default"></slot>\</section>\<footer>\<slot name="footer"></slot>\</footer>\</div>'
})const vm = new Vue({
    el:"#root"
});

在这里插入图片描述

  • 具名slot的简写
    • v-slot:header简写成#header
    • v-slot:default简写成#default
    • v-slot:footer简写成#footer
<body><div id="root"><base-layout><template #header><h4>here is header</h4></template><template #default><p>here is the section</p><p>here is the content of the section</p></template><template #footer><p>here is footer</p></template></base-layout></div>
</body>

在这里插入图片描述

<body><div id="root"><base-layout><template #header><h4>here is header</h4></template><p>here is the section</p><p>here is the content of the section</p><template #footer><p>here is footer</p></template></base-layout></div>
</body>
import Vue from "vue";Vue.component("base-layout",{
    template:'<div class="container">\<header>\<slot name="header"></slot>\</header>\<section>\<slot></slot>\</section>\<footer>\<slot name="footer"></slot>\</footer>\</div>'
})const vm = new Vue({
    el:"#root"
});
作用域slot
<body><div id="root"><current-user></current-user></div>
</body>
import Vue from "vue";Vue.component("current-user",{
    template:'<div>\<slot>{
    {user.lastname}}</slot>\</div>',data:function(){
    return {
    user:{
    firstname:"Steve",lastname:"Jobs",fullname:"Steve Jobs"}}}
})
const vm = new Vue({
    el:"#root"
});

在这里插入图片描述
但是,如果像下面这样

<body><div id="root"><current-user>{
   {user.firstname}}</current-user></div>
</body>

则会迎来“一丈红”。
在这里插入图片描述
这是因为user是组件current-user作用域下的变量,而父级访问不了组件current-user的作用域。
不过,作用域slot可以解决上面的问题。

  1. 组件current-user使用v-bind:user="user"将自身作用域下的user传递出来
  2. 父级使用v-slot:default="slotProps"通过slotProp.user接收过来
<body><div id="root"><current-user v-slot:default="slotProps">{
   {slotProps.user.firstname}}</current-user></div>
</body>
import Vue from "vue";Vue.component("current-user",{
    template:'<div>\<slot v-bind:user="user">{
    {user.lastname}}</slot>\</div>',data:function(){
    return {
    user:{
    firstname:"Steve",lastname:"Jobs",fullname:"Steve Jobs"}}}
})
const vm = new Vue({
    el:"#root"
});

在这里插入图片描述
下面是作用域slot的几种写法。

  • 第一种,v-slot:default="slotProps"
<current-user v-slot:default="slotProps">{
   {slotProps.user.firstname}}
</current-user>
  • 第二种,简写形式,#default="slotProps"
<current-user #default="slotProps">{
   {slotProps.user.firstname}}
</current-user>
  • 第三种,如果只有默认slot,可省略default,即v-slot="slotProps"
<current-user v-slot="slotProps">{
   {slotProps.user.firstname}}
</current-user>
  • 第四种,使用解构赋值,v-slot="{user}"
<current-user v-slot="{user}">{
   {user.firstname}}
</current-user>
  • 第五种,使用别名v-slot="{user:person}"
<current-user v-slot="{user:person}">{
   {person.firstname}}
</current-user>
  • 第六种,设置默认值,v-slot='{user={firstname:"Nicholas"}}'
<current-user v-slot='{user={firstname:"Nicholas"}}'>{
   {user.firstname}}
</current-user>

在这里插入图片描述

作用域slot应用于组件复用
  • 不使用作用域slot
<body><div id="root"><todo-list></todo-list></div>
</body>
import Vue from "vue";Vue.component("todo-list",{
    template:'<ul>\<li v-for="todo in list"\v-bind:key="todo.id">\{
    {todo.text}}\</li>\</ul>',data:function(){
    return {
    list:[{
    id:"#1",text:"吃饭"},{
    id:"#2",text:"睡觉"},{
    id:"#3",text:"打豆豆"}]}}
})
const vm = new Vue({
    el:"#root"
});

在这里插入图片描述

  • 使用slot作用域
<body><div id="root"><todo-list v-slot:default="{todo}"><span v-if="todo.isDone">?</span>{
   {todo.text}}</todo-list></div>
</body>
import Vue from "vue";Vue.component("todo-list",{
    template:'<ul>\<li v-for="todo in list"\v-bind:key="todo.id">\<slot name="default" v-bind:todo="todo">\{
    {todo.text}}\</slot>\</li>\</ul>',data:function(){
    return {
    list:[{
    id:"#1",text:"吃饭",isDone:true},{
    id:"#2",text:"睡觉",isDone:true},{
    id:"#3",text:"打豆豆",isDone:false}]}}
})
const vm = new Vue({
    el:"#root"
});

在这里插入图片描述

  相关解决方案