• vue2 过渡 轮播图


    ---恢复内容开始---

    Vue主要渲染条件:

      v-if:是将元素删除再创造出来进行渲染。

      v-show:是将元素的display=none掉,再进行渲染;

      要点知识:v-key:唯一元素标识,若不设置v-key,相同的名字的标签不会被从新渲染,只会瞬间改变内容。这个非常有用,轮播图就靠它了。

           只有满足将dom元素删除(v-if类似)或者display:none(v-show类似)掉,才会渲染。只改变位置,或者颜色等其他,是不会被渲染的,但这种情况,直接使用普通方法就好了,没必要用vue的过渡模式。

    两个标签:

      transition标签:将需要过渡的元素放在里面,就能进行过渡,但里面过渡的标签实际只有一个,按条件显示到底是哪一个标签。

      transition-group:里面可以放很多元素,v-for出来的元素必须放里面。里面可以设置个tag=‘p’,当显示在浏览器中时,就变成p标签。里面的元素必须设置v-key。

    两种方式:

      javascript钩子:在javascript中设置过度阶段属性。

      css方式:在css中设置过度阶段属性。

    四个阶段:

      1、enter:元素开始渲染的状态,还没有渲染。

      2、enter-to(active):这两个区别搞不明白,这个不行就换另一个。就是目标状态,从enter 到enter-to的状态,transition:all 3s就写在这个状态下。

      3、leave:开始删除或者隐藏元素,开始前的位置或者状态。

      4、leave-to(active):到达这个状态时元素被删除或者隐藏。是过度状态。跟2相同。

    无缝轮播图类型:这儿做一张图可见、有圆点,点击可选择图片、左右点击可切换,一共7张图,清理bug。

    思路:

      首先要明白渲染条件:见vue的渲染条件。

      主要思路:轮播图中,它显示的那张图片在浏览器中可以看到有dom元素。隐藏的是没有dom元素的。所以如果显示一张图片,实际上,轮播列表中只有一个元素是存在的,其他的都被删掉了。按照这个思路,就很简单了。想要轮播,设置:enter:右边→enter-to:正常位置,并且过渡完成→leave:正常位置→leave-to:左边,并且过渡完成。

      

      需了解:当它开始渲染新的一张的时候,旧的那一张会与新的一张同时存在,这就有2个元素。当旧的那一张过渡时间完成后,就会被删除。

      代码如下:

    html:
    <div>
      <button @click='next'>下一张</button>
      <button @click='last'>上一张</button>
      <ul class='ul'>
        <li>
          <transition :name='tr'>   <!--必须设置name,放入其中的元素能够过度--> 
            <img :src='src' :key='src'> <!--当src改变了,这张图就消失了,满足类似v-if的渲染条件。必须设置key值,因为都是img元素,不设置会只改变图片,不进行切换--> 
          </transition>
        </li>
      </ul>
      <ul class='ul2'>  <!--这儿放7个圆点,并且绑定click,--> 
        <li v-for='num in 7' :style="{color:num==n?'red':'green'}" @click='change(num)' class='li' >●</li>
      </ul>       <!--当num==n(当前显示元素的索引)的时候,圆点变为红色,其他为绿色--> 
     
    </div>
    javascript:
    data(){    //如果是普通页,需该为data:{}
      return{
        n:1,         //图片的index。
        tr:'tr1',      //trnsition 标签的name值,我写了2套css方案,因为你点下一张,它往左运动,点上一张它往右运动。
        timeout1:'',    //这是flag定时器的数据
        timeout2:'',    //这是自动播放(next())定时器的数据
        timeout3:'',    //这是打开浏览器时,初始运动定时器的数据
        flag:true,
      }
    },
    methods:{
      next(){                  //下一张
        if(this.flag){            //为了避免连续点击。让flag运动结束后再变为true。
          this.flag=false;  
          this.clearT();          //运动之前,清除所有定时器。
          this.n=this.n+1==8?1:this.n+1; //下一张,如果是第8张,就返回第一张。
          this.tr='tr1';          //css方案切换到tr1,就是transition的name属性变为tr1。
          this.timeout()          //调用timeout函数,其作用是等待下一次轮播,调整flag,以便可以点击切换。
        }
      },
      last(){                   //上一张,跟next方向相反
        if(this.flag){
          this.flag=false;
          this.clearT();
          this.n=this.n-1==0?7:this.n-1; //当它变为第1张时,下一张就是第7张。
          this.tr='tr2';          //切换css方案2
          this.timeout()                 
        }
      },
      clearT(){                  //清除所有定时器。
        clearTimeout(this.timeout1);     
        clearTimeout(this.timeout2);
        clearTimeout(this.timeout3);
      },
      timeout(){                //运动结束后设置flag为true,并且过3秒调用next,进行下一次运动。
        this.timeout2=setTimeout(()=>{this.flag=true},1050); //运动时间是1s。
        this.timeout1=setTimeout(()=>{this.next()},3000);
      },
      change(num){              //点击小黑点,切换到那一张,需要将这一个圆点的num传下来。
        if(this.flag){
          this.flag=false;
          this.clearT();    
          this.tr = num-this.n>0?'tr1':'tr2';  //看选择css1方案还是css2方案。
          this.n=num;                //将显示那一张变为选中的那一张。      
          this.timeout()              
        }
      },
    },
    computed:{
      src(){                      //地址,这儿取巧了,this.n与图片编号对应。
        return './src/assets/'+this.n+'.jpg'
      },
    },
    mounted(){
      this.timeout3=setTimeout(this.next,3000);  //刚挂载dom,就开始等待进行第一次轮播,
      }
    }
    //css
    //杂项布局 可忽略
    *{
      margin:0;
      padding:0;
    }
    li{
      list-style:none;
      position:relative;//设置为相对位置。
    }
    img{
      500px;
      height:250px;
      margin:0 auto;
      display:inline-block;
      position:absolute; //设置绝对定位
    }
    .ul{
      500px;
      height:250px;
      margin:0 auto;
      overflow:hidden;
    }
    .ul2{
       200px;
      position:relative;
      left:50%;
      margin-left:-100px;
      top:-30px;
      text-align:center;
    }
    li.li{
      font-size:25px;
      float:left;
      cursor:pointer;
      transition:all 1s;      //我在这儿设置普通过度,这儿是红色与绿色转变。
    }
     
     
    //方案一 让图片从右往左运动。
    .tr1-enter{
      opacity:0;
      left:100%;  //从左边开始进入。
    }
    .tr1-enter-to{
      left:0;        //过度到正常位置,必须写,position定位不写,会是默认位置,可能不是left:0这儿。
      transition:all 1s;//过度一秒
      opacity:1;
    }
    .tr1-leave{        //离开动画
      left:0;
      opacity:1;
    }
    .tr1-leave-to{
      transition:all 1s;
      opacity:0;
      left:-100%      //正常位置过度到左边,然后消失。
    }
     
    //方案二:与方案一方向是反的,其他全部相同。
    .tr2-enter{
      opacity:0;
      left:-100%;
    }
    .tr2-enter-to{
      left:0;
      transition:all 1s;
      opacity:1;
    }
    .tr2-leave{
      left:0;
      opacity:1;
    }
    .tr2-leave-to{
      transition:all 1s;
      opacity:0;
      left:100%
    }

    遗留问题:

      当使用transitionend事件代替定时器触发图片运动后执行代码时,发现并不理想,有时候运动结束后并不能触发@transitionend事件,猜测是过渡时出现了2个img元素,transitionend会分别探测2个元素动画结束,如果有2中style过度,就是应该一次动画触发4次transitionend,但触发次数并不是稳定在4次,非常奇怪。

      还有种方式就是不用position,使用transform,但是很遗憾,ie貌似并不支持。

      v-enter-to与v-enter-active区别不明。如果enter-to是代替enter-active的,那在transition-group中,enter-to是不比enter-active好用的,官网的例子可以说明。

      

  • 相关阅读:
    【HTML】WebStorage
    【vue.js】vue项目使用Iconfont(阿里图标库)
    【CSS】水平居中和垂直居中
    【设计模式】责任链模式
    【设计模式】观察者模式
    【设计模式】策略模式
    【排序算法】(9)堆排序
    【排序算法】(5)基数排序
    【排序算法】(6)选择排序
    简单权限设计表
  • 原文地址:https://www.cnblogs.com/gsgs/p/6698494.html
Copyright © 2020-2023  润新知