• 第三十八篇 Vue中封装Swiper组件 2.0


             上一篇内容讲到封装Swiper组件的一个过程,如果是静态的数据封装组件初始化在mounted当中并无多大影响,但是这样封装的组件复用性较低或者可能只使用一次,那么在动态使用通过ajax请求数据需要面临的是swiper初始化过早的问题,在mounted生命周期中初始化会导致swiper组件的创建完成但swiper中的轮播数据还未准备好造成swiper没法轮播起来,而在updated当中做swiper的初始化能够使swiper的轮播能够正常进行,但存在的问题一旦data数据中的状态改变会引起updated中的swiper初始化重复执行,具有一定隐患,所以在updated当中是不能够进行swiper初始化工作,转而到mounted生命周期当中来,通过设置key值的方式,设置key值的这种方式是在讲这个diff算法如何进行虚拟DOM的对比,不设置key值前在mounted生命周期当中初始化是swiper为了提高用户体验和效率,保留了swiper标签只替换了swiper中的数据,如果设置key值,swiper组件前后的key比对不同,Vue会将之前的swiper删除然后重新创建,此时swiper当中的数据已经准备好了可以进行swiper初始化工作,这样一来swiper组件的封装就已经告一段落了!


            以上的内容是对上一篇内容的总结回顾,那么既然已经解决了那些问题,swiper组件也能够成功的运行起来,封装组件不就到此结束了吗? 即使这样我们仍然还有一些需要进一步的发掘。先将上一篇内容的代码整理一份在这里继续讲解:

    1. <div id="app">
    2. <swiper :key="swiperList.length">
    3. <div class="swiper-slide" v-for="(item,index) in swiperList" :key="index">
    4. <img :src="item" />
    5. div>
    6. swiper>
    7. div>
    8. <script>
    9. Vue.component("swiper",{
    10. template:`
  • `,
  • mounted(){
  • new Swiper(".author",{
  • loop:true,
  • autoplay:{
  • delay:2000
  • },
  • pagination:{
  • el:'.swiper-pagination'
  • }
  • })
  • }
  • })
  • new Vue({
  • el:'#app',
  • data:{
  • swiperList:[] // 请求的数据容器
  • },
  • mounted(){
  • // 模拟发起ajax请求
  • setTimeout(()=>{
  • this.swiperList = [
  • 'https://s2.loli.net/2022/07/18/1nMDLzF35hsYZ8t.jpg' ,
  • 'https://s2.loli.net/2022/07/18/yFXUisGht9x5PjY.jpg' ,
  • 'https://s2.loli.net/2022/07/18/8WhpU5EDQTySONY.jpg' ];
  • },2000)
  • }
  • })
  • script>
  • " v-if " 指令 

          以上通过上一篇的回顾和代码可以知道的是设置key值的这套过程换一个思路就是swiper组件在创建的时候要进行mounted生命周期对swiper进行初始化,前提是swiperList已经装备好了,这样才能够让swiper轮播起来,说到这你可能会想到有一个指令好像可行,谁呢?" v-if " 指令;通过判断swiperList.length来确定swiperList是否有数据,如果有的话在创建swiper组件然后swiper组件进入mounted生命周期对swiper进行初始化,这样一来swiper组件不也可以轮播起来了吗?

    1. 代码编写:

    1. <div id="app">
    2. <swiper v-if="swiperList.length">
    3. <div class="swiper-slide" v-for="(item,index) in swiperList" :key="index">
    4. <img :src="item" />
    5. div>
    6. swiper>
    7. div>

    2. 测试效果:

            通过v-if指令判断swiperList是否为真,也即是swiperList已经有数据了,此时创建swiper进入mounted生命周期进行swiper初始化,一次就能够成功!这也不失为封装组件的一个好办法!


    封装Swiper组件的灵活性

            封装完swiper组件后会发现当我使用的时候不需要用这个指示器(圆点),那我怎么去掉呢?显然组件好像还不够灵活,可以使用之前讲过的哪些知识点呢?就是这个插槽,通过插槽的方式,如果使用者不想要这个图片指示器的话,就可以不传指示器,让组件变得更加的灵活;

            下面使用新版的slot,在讲新版本插槽的时候讲过要注意版本问题,同时要结合template标签进行包裹使用,同时还有简写,这里附上地址,回顾温习一下:  第三十一篇 v-slot 插槽使用

    1. 编写代码

    1. <div id="app">
    2. <swiper v-if="swiperList.length">
    3. <div class="swiper-slide" v-for="(item,index) in swiperList" :key="index">
    4. <img :src="item" />
    5. div>
    6. <template #pagination>
    7. <div class="swiper-pagination">div>
    8. template>
    9. swiper>
    10. div>
    11. <script>
    12. Vue.component("swiper",{
    13. template:`
    14. <div>
    15. <div class="swiper-container author" >
    16. <div class="swiper-wrapper">
    17. <slot>slot>
    18. div>
    19. <slot name="pagination">slot>
    20. div>
    21. div>
    22. `,
    23. ...

    2. 去掉