Vue插槽的使用

177 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第五天,点击查看活动详情


前言

最近笔者学习了有关Vue插槽的知识,也做了一些小案例加深了对其的理解。本文笔者便分享出来自己对于它的理解。

原理

官方对于插槽作用的定义是这样的:让父组件可以向子组件指定位置插入html结构。很多人看到可能会有点难以理解,别急,让我们通过一个小案例来讲解。首先,我们有一个父组件School和一个子组件student,分别展示了以下的内容。

image.png

但这时候父组件就说了:哎,那啥啥啥student怎么只展示了这个,我有一个学生列表数据,你给我展示出来。这是子组件听见了就答应:好嘞!就在自己的组件中写了一个列表给他展示出来。

School.vue:

<Student :listData="studentInfo"/>

Student.vue:

  <ul>
      <li v-for="(item,index) in listData" :key="item.id">
          {{item}}
      </li>
  </ul>

效果

image.png

但这时候School组件又有一个学生宿舍的信息要展示,便多叫了一个学生来干活。

School.vue

  <Student :listData="studentInfo"/>
  <Student :listData="dormitoryInfo"/>

效果

image.png

但这个时候School又说了我宿舍信息不想展示列表了,我有个宿舍图你给我展示一下,这时候子组件又完成了甲方(学校)的任务

Student.vue

  <!-- <ul>
      <li v-for="(item,index) in listData" :key="item.id">
          {{item}}
      </li>
  </ul> -->
  <img :src="listData" alt="">

image.png

甲方(学校)看到效果之后就说哎,你咋把我学生列表整没了呢,让你做个事情都做不好,下去操场给我跑两圈(开玩笑)。这个时候插槽表现的时候就来了。

Student.vue

<h3>这是子组件student</h3>
<slot></slot>

School.vue

  <Student>
    <ul>
      <li v-for="(item,index) in studentInfo" :key="item.id">
          {{item}}
      </li>
  </ul>
  </Student>
  <Student>
      <img :src="dormitoryImg" alt="">
  </Student>

效果

image.png

这个时候甲乙方(School和Student)都露出了笑脸。好了,这个时候我们就知道插槽的使用场景了:当你有很多的页面都一样,其中只有部分的结构不同(例如上文的学生信息和宿舍图),便可以使用插槽插槽分为

1.默认插槽(匿名插槽)

2.具名插槽:比如说你一个页面有很多插槽

<slot></slot><slot></slot><slot></slot>

这个时候你父组件传入结构怎么知道谁是谁呢?这个时候只要这样(以上文为例)

student.vue

<slot name="studentInfo"></slot>
<slot name="dormitoryImg"></slot>

School.vue

  <Student >
      <--这种方法不建议,div占用一个结构,在浏览器中会显示-->
  <div slot="studentInfo">
    <ul>
      <li v-for="(item,index) in studentInfo" :key="item.id">
          {{item}}
      </li>
    </ul>
  </div>
  </Student>
  <Student>
      <--使用模板template不占用结构,推荐使用-->
          <--slot="dormitoryImg"也可直接用#dormitoryImg简写
    (等于v-slot="dormitoryImg")-->
      <template slot="dormitoryImg">
       <img :src="dormitoryImg" alt="">
      </template>
  </Student>

还有一个就是作用域插槽 就是数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。对于上面的案例来说就是studentInfo列表数据在Student组件中,但使用数据所遍历出来的结构由School组件决定

上面案例的数据我都是放在父组件School当中,现在比如说学生信息的数据我给他放到Student组件中,现在School组件用有序列表遍历,无序列表遍历我也给他留着。

这个时候子组件的代码就需要改成这样

<--studentInfo在Student组件的data中-->       
<slot :studentInfo="studentInfo"></slot>

然后父组件通过scope获取数据,注意这时候获取的不是student列表数据

要通过 xx.studentInfo才能获取到

    <Student>
      <template scope="data"> 
        <ol>
          <li v-for="(item, index) in data.studentInfo" :key="item.id">
            {{ item }}
          </li>
        </ol>
      </template>
    </Student>

效果

image.png

总结

好了,以上就是笔者学习的有关Vue插槽的内容了,毕竟笔者能力有限,有错误的地方希望可以提出来,我们一起进步,谢谢!