vue進入/離開 & 列表過渡transition

一.transition過渡css

1.需求1(優化):想要一種效果,想要ios那種頁面切換效果,總而言之就是過渡效果。html

附上官網介紹地址:https://cn.vuejs.org/v2/guide/transitions.htmlvue

1.ios

App.vue代碼片斷以下:正則表達式

<template>
  <div id="app">
    <transition :name="transitionName">
      <keep-alive>
         <router-view  v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
    </transition>
    <transition :name="transitionName">
         <router-view v-if="!$route.meta.keepAlive"></router-view>
    </transition>
  </div>
</template>

以上是HTML上的代碼,在keep-alive外層,增長transition,而且綁定name屬性transitionName(這個是一個變量,用來控制想要加的樣式前綴),看了下面的代碼你就懂了:vue-router

watch: {//使用watch 監聽$router的變化
   $route(to, from) {
      //若是to索引大於from索引,判斷爲前進狀態,反之則爲後退狀態
      if(to.meta.index > from.meta.index){
          //設置動畫名稱
          this.transitionName = 'slide-left';
      }else{
          this.transitionName = 'slide-right';
      }
   }
}


 

 

import Vue from 'vue';
import VueRouter from 'vue-router'

import Home from '@V/home'
import List from '@V/list'
import Approve from '@V/approve'
import DetailInfo from '@V/detailInfo'
import Info from '@V/info'

Vue.use(VueRouter)

export const routes = [
  {
    path:'/',
    name:'home',
    component:Home,
    meta: {
      keepAlive: false,
      index:1
    },
  },
  {
    path:'/list',
    name:'list',
    component:List,
    meta: {
      keepAlive: true,
      index:2
    },
  },
  {
        path:'/approve',
        name:'approve',
        component:Approve,
        meta: {
            keepAlive: false,
            index:3
        },
    },
    {
        path:'/detailInfo',
        name:'detailInfo',
        component:DetailInfo,
        meta: {
            keepAlive: false,
            index:3
        },
    },
    {
        path:'/info',
        name:'info',
        component:Info,
        meta: {
            keepAlive: false,
            index:4
        },
    }
]

 

看到這裏估計你僅僅是知道transition變量是根據頁面切換to和from索引來控制值,其實這個值是一個過渡類名的前綴,用來拼接transition的過渡狀態,如下引用官方的解釋:緩存

 

過渡的類名

在進入/離開的過渡中,會有 6 個 class 切換。session

  1. v-enter:定義進入過渡的開始狀態。在元素被插入以前生效,在元素被插入以後的下一幀移除。app

  2. v-enter-active:定義進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入以前生效,在過渡/動畫完成以後移除。這個類能夠被用來定義進入過渡的過程時間,延遲和曲線函數。less

  3. v-enter-to: 2.1.8版及以上 定義進入過渡的結束狀態。在元素被插入以後下一幀生效 (與此同時 v-enter 被移除),在過渡/動畫完成以後移除。

  4. v-leave: 定義離開過渡的開始狀態。在離開過渡被觸發時馬上生效,下一幀被移除。

  5. v-leave-active:定義離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時馬上生效,在過渡/動畫完成以後移除。這個類能夠被用來定義離開過渡的過程時間,延遲和曲線函數。

  6. v-leave-to: 2.1.8版及以上 定義離開過渡的結束狀態。在離開過渡被觸發以後下一幀生效 (與此同時 v-leave 被刪除),在過渡/動畫完成以後移除。

   對於這些在過渡中切換的類名來講,若是你使用一個沒有名字的 <transition>,則 v- 是這些類名的默認前綴。若是你使用了 <transition name="my-transition">,那麼 v-enter 會替換爲 my-transition-enter

 

以上是官方的解釋,下面看看css是怎麼寫的:

.slide-right-enter-active,
  .slide-right-leave-active,
  .slide-left-enter-active,
  .slide-left-leave-active {
    will-change: transform;
    transition: all 500ms;
    position: absolute;
  }
  .slide-right-enter {
    opacity: 0;
    transform: translate3d(-100%, 0, 0);
  }
  .slide-right-leave-active {
    opacity: 0;
    transform: translate3d(100%, 0, 0);
  }
  .slide-left-enter {
    opacity: 0;
    transform: translate3d(100%, 0, 0);
  }
  .slide-left-leave-active {
    opacity: 0;
    transform: translate3d(-100%, 0, 0);
  }

以上就是把transition的狀態寫了個過渡樣式,加上這樣的代碼,你就能夠實現需求一。附上完整代碼:

<template>
  <div id="app">
    <transition :name="transitionName">
      <keep-alive>
         <router-view  v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
    </transition>
    <transition :name="transitionName">
         <router-view v-if="!$route.meta.keepAlive"></router-view>
    </transition>
  </div>
</template>

<script>


  export default {
    name: 'app',
    data(){
      return {
        // text:sessionStorage.getItem('parameters')
          transitionName:''
      }
    },
      watch: {//使用watch 監聽$router的變化
          $route(to, from) {
              //若是to索引大於from索引,判斷爲前進狀態,反之則爲後退狀態
              if(to.meta.index > from.meta.index){
                  //設置動畫名稱
                  this.transitionName = 'slide-left';
              }else{
                  this.transitionName = 'slide-right';
              }
          }
      }
  }
</script>

<style lang="less">
  @import '~vux/src/styles/reset.less';

  #app{
    /*position: relative;*/
  }
  body {
    background-color: #fbf9fe;
  }
  .vux-x-icon {
    fill:#1d83ef;
  }
  .backicon {
    width:38px;
    height:38px;
    display:inline-block;
    border-radius:100%;
    border:1px solid #1d83ef;

  }
  .slide-right-enter-active,
  .slide-right-leave-active,
  .slide-left-enter-active,
  .slide-left-leave-active {
    will-change: transform;
    transition: all 500ms;
    position: absolute;
  }
  .slide-right-enter {
    opacity: 0;
    transform: translate3d(-100%, 0, 0);
  }
  .slide-right-leave-active {
    opacity: 0;
    transform: translate3d(100%, 0, 0);
  }
  .slide-left-enter {
    opacity: 0;
    transform: translate3d(100%, 0, 0);
  }
  .slide-left-leave-active {
    opacity: 0;
    transform: translate3d(-100%, 0, 0);
  }
</style>

 

註明:上週5同事發現了一個bug,發現用transition以後,切換頁面的時候可能可能可能會出現一個問題:會出現短暫的白板!!!同事說,多是加了transition左右滑動的時候定位出現的問題,因此出現短暫白板。當時的解決方案就是,在app.vue中的,給#app加了個樣式,position:relative,其餘的子組件每一個最外層都加了個position:absolute。這樣就完美解決了。不過今天寫博客的時候,我又實驗了一把,沒出現白板的問題。若是出現以上問題,就試試加個定位吧。

另外,還有個bug,上面的代碼,是經過v-if去判斷緩存,並且有兩個transition,運行起來發現,切換頁面的時候交替閃現,其實,這裏也猜到了,是兩個transition經過v-if判斷的時候,出現的交錯的bug。下面繼續完善上面的需求:

 下面是文檔介紹:

include - 字符串或正則表達式。只有匹配的組件會被緩存。 
exclude - 字符串或正則表達式。任何匹配的組件都不會被緩存。

下面貼上更改後app.vue的代碼:

<template>
  <div id="app">
    <transition :name="transitionName">
      <keep-alive include="list">
         <router-view></router-view>
        <!--<router-view  v-if="$route.meta.keepAlive"></router-view>-->
      </keep-alive>
    </transition>
    <!--<transition :name="transitionName">
         <router-view v-if="!$route.meta.keepAlive"></router-view>
    </transition>-->
  </div>
</template>

app.vue其餘地方不變,這裏引入的include(固然,若是你喜歡用exclude也能夠,相反而已,排除引號內的組件名字,之外的都要緩存)是要緩存的組件name,多個緩存頁面name用逗號分隔。好比:include="list,info,home"

因此路由頁面的頁不用設置meta:{keepAlive:true}了,路由代碼以下:

export const routes = [
  {
    path:'/',
    name:'home',
    component:Home,
    meta: {
      index:1
    },
  },
  {
    path:'/list',
    name:'list',
    component:List,
    meta: {
      index:2
    },
  },
  {
        path:'/approve',
        name:'approve',
        component:Approve,
        meta: {
            index:3
        },
    },
    {
        path:'/detailInfo',
        name:'detailInfo',
        component:DetailInfo,
        meta: {
            index:3
        },
    },
    {
        path:'/info',
        name:'info',
        component:Info,
        meta: {
            index:4
        },
    }
]

 

over,這是今天的內容,本身的一份記錄,也但願對你有幫助。

相關文章
相關標籤/搜索