---恢復內容開始---
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好用的,官網的例子可以說明。