当vue遇到swiper

2,433 阅读2分钟

我们这里的解决方案主要是针对动态获取数据的情况,如果您是静态页面就很好解决了,百度走起即可
你是不是有这样的困惑:vue环境下使用swiper出现各种问题,举个栗子:

  • swiper实例化后图片资源压根不加载
  • 加载了但是没有轮播效果
  • 偶尔需要横竖屏切换一下才可以动起来(移动端)...

首先我们看看swiper的实例化原理:
1.找到父级container包裹层
2.给这个父级的尾部逐个添加子元素
3.不要画蛇添足,除了父级元素你可以龟腚(规定)大小以及位置,内部子元素不要乱加定位
4.得到元素后,进行补帧,形成循环轮播效果
5.至于动画,其swiper.css做了大量的transform变形以及动画

接下来我们说说vue的数据获取:
现在vue已经更新了,较多的使用axios进行交互,当然你可以接续使用vue-resource(官方不再更新),不管你的数据库使用的是mysql还是mongodb,我们读取数据时都有一定的时间,所以获取数据都是异步的,说的白一些就是你前台的页面渲染和我的数据获取不是同步的,你做你的我干我的,这就导致一个顺序问题,到底是vue的数据获取在先,还是我swiper实例化在先,我们想要的肯定是数据加载完毕,再开始实例化

其实说到这里,比较来气,网上好多“程序员”拿vue的钩子函数(生命周期)说这个问题,其实不管你用created还是mounted,都不是解决这个问题的关键所在,其关键点在于异步加载和dom的更新。

具体解决方案
不管你是在created阶段还是mounted阶段都可以实现最终效果,代码如下

    export default {
       data() {
          return {
            banner:[]
          }
        },
       methods: {
         _initBanner() {
             let swiperContainer = this.$refs.swiper;
             let swiperComp = new Swiper(swiperContainer, { //实例化一个cube轮播
                 autoplay: 2000,
                 autoplayDisableOnInteraction : false,
                 loop:true,
                 effect: 'cube',
                 cube: {
                     shadow: true,
                     slideShadows: true,
                     shadowOffset:18,
                     shadowScale:0.88
                 }
             })
         } 
       },
       created() {  //本例中你可以改为mounted
           this.$http.get('/api/getbanner').then((res)=>{
            this.banner = res.data;
           //console.log(this.banner);
              this.$nextTick(() => {   //修改数据之后立即使用这个方法,获取更新后的 DOM
              this._initBanner()
            })
          })

       }
    }

记得在获取数据后实例化swiper组件,并且添加nextTick方法,获取dom的更新状态。