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{
  width:500px;
  height:250px;
  margin:0 auto;
  display:inline-block;
  position:absolute; //設置絕對定位
}
.ul{
  width:500px;
  height:250px;
  margin:0 auto;
  overflow:hidden;
}
.ul2{
  width: 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好用的,官網的例子可以說明。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM