slot,插槽二三事

文章知识点

1,插槽基本使用

2,具名插槽

3,作用域插槽

在这里插入图片描述

什么是插槽

slot即插槽。
生活中,我们都知道USB插槽,USB插槽可以连接其他设备,从而进行操作。Vue的插槽跟它的功能类似。

使用插槽的目的:即使原有的Vue组件更具扩展行。

插槽的基本使用

在使用时,直接在组件模板中使用<slot></slot>标签,即完成预留插槽。
话不多说,上实例

<body>
    <div id="app">
        <!-- 在组件标签中使用span、i或者其他标签并在里面写入内容即可替换slot -->
        <cpn><span>用笔者,天也,流美者,地也</span></cpn>
        <cpn><i>横如千里阵云,折如百钧弩发</i></cpn>
    </div>
    <template id="tem">
        <div>
            <h3>善书者自有风骨,尽一身之力而颂之</h3>
            <!-- 预留插槽 -->
            <slot></slot>
        </div>
        
    </template>
    <script src="./js/vue.min.js"></script>
    <script>
        let cpn = {
            template:"#tem"
        }
        Vue.component("cpn",cpn)
        let app = new Vue({
            el:"#app"
        })
    </script>
</body>

效果图:
在这里插入图片描述

具名插槽

具名插槽,就是具有名字的插槽。对,起名就是这么随便嘿!
假如说,我现在有一个组件

<body>
    <div id="app">
        <cpn></cpn>
        
    </div>
    <template id="tem">
        <div>
            <!-- 插槽也可以设置默认值 -->
            <slot ><span>左边</span></slot>
            <slot ><span>中间</span></slot>
            <slot><span>右边</span></slot>
        </div>
        
    </template>
    <script src="./js/vue.min.js"></script>
    <script>
        let cpn = {
            template:"#tem"
        }
        Vue.component("cpn",cpn)
        let app = new Vue({
            el:"#app"
        })
    </script>
</body>

显示在页面上

那么我现在有个需求,想把中间那个插槽替换,而其他不变,该如何实现呢?
肯定是不能直接替换的,因为你替换一个那全部的内容都会变。此时,我们的具名插槽就闪亮登场了!
我们可以在模板中给插槽定义一个name属性,然后在渲染的时候指定这个插槽即可

<body>
    <div id="app">
        <cpn><span slot="center">我要在中间</span></cpn>
        
    </div>
    <template id="tem">
        <div>
            <!-- 插槽也可以设置默认值 -->
            <slot ><span>左边</span></slot>
            <slot name="center"><span>中间</span></slot>
            <slot><span>右边</span></slot>
        </div>
        
    </template>
    <script src="./js/vue.min.js"></script>
    <script>
        let cpn = {
            template:"#tem"
        }
        Vue.component("cpn",cpn)
        let app = new Vue({
            el:"#app"
        })
    </script>
</body>

那我们就替换完成了

作用域插槽

编译作用域

在整明白啥叫作用域插槽之前,我们先了解一下编译作用域。
当vue实例data中有一个属性跟组件中data的属性名是相同时,在vue实例作用范围内即组件标签会使用vue实例中的data里的属性,但在组件作用范围模板中则会使用组件中data的属性。
用一句话解释就是父组件模板中的所有代码都会在父级作用域中编译,同样的子组件模板中的所有代码也都会在子级作用域中编译
Emma,语言真苍白,看实例吧

<body>
  <div id="app">
  <!-- 此时的isShow会使用vue实例中的isShow -->
    <cpn v-show="isShow"></cpn>
  </div>
  
  <template id="tem">
    <h2>剑指的方向,就是天才的故乡</h2>
  </template>
  <script src="./js/vue.js"></script>
  <script>
    const cpn = {
      template:"#tem",
      isShow:false
    }
    const app = new Vue({
      el:"#app",
      data:{
       <!-- 如果你把这里的true改成false那页面就不会显示内容 那就证明用的正是这里的isShow-->
        isShow:true
      },
      components:{
        cpn
      }
     } )

那此时我们打开页面,那个天才少年的豪言壮语会显示在页面上,如下图

如果我在模板里再加一句,如下:

<template id="tem">
    <div>
      <h2>剑指的方向,就是天才的故乡</h2>
      <h3 style="color: red;" >角木犹比蛟,亢金宛如龙,尾火形似虎、箕水貌若豹……</h3>
    </div>

页面显示图:

如果我在h3里加一个v-show,那它用的就是组件里的data中的isShow属性,即页面不会显示上图红色字

<body>
  <div id="app">
    <cpn v-show="isShow"></cpn>
  </div>
  
  <template id="tem">
    <div>
      <h2>剑指的方向,就是天才的故乡</h2>
       <!-- 看这里 -->
      <h3 style="color: red;" v-show="isShow">角木犹比蛟,亢金宛如龙,尾火形似虎、箕水貌若豹……</h3>
    </div>
    
  </template>
  <script src="./js/vue.js"></script>
  <script>
    const cpn = {
      template:"#tem",
       <!-- 此时的isShow会使用这里中的isShow -->
      isShow:false
    }
    const app = new Vue({
      el:"#app",
      data:{
        isShow:true
      },
      components:{
        cpn
      }
     } )
  </script>
</body>

呐,这就是编译作用域了。

作用域插槽

为啥在讲作用域插槽时,我要先费劲巴拉的说一下编译作用域呢,因为作用域插槽就符合编译作用域的原理的
现在我有一个组件,并且把组件里的数据渲染到页面上

<body>
  <div id="app">
    <div>
      <cpn></cpn>
    </div>
  </div>
  <template id="tem">
    <div>
      <slot>
        <ul>
          <li v-for="item in hero">{{item}}</li>
        </ul>
      </slot>
    </div>
  </template>
  <script src="./js/vue.js"></script>
  <script>
    const cpn = {
      template:'#tem',
      data(){
        return {
          hero:['小鲁班','李元芳','后羿','马可波罗','虞姬']
        }
      }
    }
    const app = new Vue({
      el:"#app",
      components:{
        cpn
      }
    })
  </script>
</body>

页面显示如下:

我现在的需求是,当我第二次使用时,我不想让让数据这么排列,我想要横着且用*隔开,注意必须要用组件data 里hero属性的数据渲染哦,像这样,

由于编译作用域,我直接用hero里的数据是拿不到的。
那怎么实现呢?
我们可以先在插槽中自定义一个属性,把子组件的hero赋值给这个属性

<template id="tem">
    <div>
    <!-- 自定义一个data属性并赋值 -->
      <slot :data="hero">
        <ul>
          <li v-for="item in hero">{{item}}</li>
        </ul>
      </slot>
    </div>

在第二次使用组件标签时,用一个template标签 也可以用别的html标签比如div,但为了更好的兼容最好还是用template。

<cpn>
        
        <!-- 在template中使用 -->
        <template slot-scope="slot">
          <span v-for="item in slot.data">{{item}}*</span>
        </template>
      </cpn>


但最后还有一个*,真是难死强迫症。因为hero是一个数组,所以我们可以用join方法拼接啊。改良版如下

 <cpn>
        
        <!-- 在template中使用 -->
        <template slot-scope="slot">
          <!-- <span v-for="item in slot.data">{{item}}*</span> -->
          <span>{{slot.data.join('*')}}</span>
        </template>
      </cpn>


嗯,舒服多了~
完整代码附上

<body>
  <div id="app">
    <div>
      <cpn></cpn>
      <!-- 当我展示第二次的时候每个英雄之间我想用一个*隔开 -->
      <cpn>
        
        <!-- 在template中使用 -->
        <template slot-scope="slot">
          <!-- <span v-for="item in slot.data">{{item}}*</span> -->
          <span>{{slot.data.join('*')}}</span>
        </template>
      </cpn>
    </div>
  </div>
  <template id="tem">
    <div>
      <slot :data="hero">
        <ul>
          <li v-for="item in hero">{{item}}</li>
        </ul>
      </slot>
    </div>
  </template>
  <script src="./js/vue.js"></script>
  <script>
    const cpn = {
      template:'#tem',
      data(){
        return {
          hero:['小鲁班','李元芳','后羿','马可波罗','虞姬']
        }
      }
    }
    const app = new Vue({
      el:"#app",
      components:{
        cpn
      }
    })
  </script>
</body>

这,就是插槽~
在这里插入图片描述

Vue中的插槽Slots)是一种在父组件中将子组件的内容进行分发的机制。通过插槽,我们可以在父组件中定义一些占位符,然后在子组件中填充具体的内容。 在Vue中,插槽有两种类型:具名插槽和默认插槽。 具名插槽允许我们在父组件中使用多个不同的插槽,并且可以根据需要进行分发和填充。我们可以使用`<slot>`元素和`name`属性来定义具名插槽。例如: ```html <!-- 父组件 --> <template> <div> <slot name="header"></slot> <slot></slot> <slot name="footer"></slot> </div> </template> <!-- 子组件 --> <template> <div> <slot name="header"> <!-- 默认插槽内容 --> <h1>默认标题</h1> </slot> <p>子组件内容</p> <slot name="footer"> <!-- 默认插槽内容 --> <p>默认页脚</p> </slot> </div> </template> ``` 在上面的例子中,父组件定义了三个插槽:`header`、默认插槽和`footer`。子组件可以根据需要填充这些插槽,并且如果没有提供相应的内容,那么会显示插槽中的默认内容。 默认插槽是没有名字的插槽,如果在父组件中没有定义具名插槽的话,子组件的内容会被分发到默认插槽中。 除了使用`<slot>`元素和`name`属性来定义插槽,我们还可以使用`<template>`元素和`v-slot`指令来定义和填充插槽。例如: ```html <!-- 父组件 --> <template> <div> <template v-slot:header> <!-- 插槽内容 --> </template> <!-- 默认插槽内容 --> <template v-slot:default> <!-- 插槽内容 --> </template> <template v-slot:footer> <!-- 插槽内容 --> </template> </div> </template> ``` 使用插槽可以使我们的组件更具灵活性,可以根据需要在父组件中定制子组件的部分内容。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值