zoukankan      html  css  js  c++  java
  • 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好用的,官网的例子可以说明。

      

  • 相关阅读:
    [译文] 实体与值对象到底是不是一回事?
    实现 WebApi 自托管服务宿主于 WinForms 及其交互
    [译文] C# 8 已成旧闻, 向前, 抵达 C# 9!
    [译文] 为什么你在 C# 里总是应该使用 "var" 关键字
    通过设置iis在局域网中访问网页
    windows 10 安装使用kafka
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 2) 定义命名化和类型化的客户端
    Asp.net Core 2.0 OpenId Connect Handler缺失Claims?
  • 原文地址:https://www.cnblogs.com/gsgs/p/6698494.html
Copyright © 2011-2022 走看看