vue内置transition组件

62 阅读3分钟

主要用于场景转换的过渡, 可以写任何css代码

1、CSS对应的class名

进入:.v-enter 初始状态、.v-enter-to 末尾状态、.v-enter-active 进入动画

离开:.v-leave 初始状态、.v-leave-to 末尾状态、.v-leave-active 离开动画

-  条件渲染 (使用 `v-if`)
-  条件展示 (使用 `v-show`)

- [class 类名]

0.  `v-enter`:**定义进入过渡的开始状态**。在元素被插入之前生效,在元素被插入之后的下一帧移除。
0.  `v-enter-active`:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来**定义进入过渡的过程时间**,**延迟和曲线函数**。
0.  `v-enter-to`2.1.8 版及以上**定义进入过渡的结束状态**。在元素被插入之后下一帧生效 (与此同时 `v-enter` 被移除),在过渡/动画完成之后移除。
0.  `v-leave`:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
0.  `v-leave-active`:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
0.  `v-leave-to`:**2.1.8 版及以上**定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 `v-leave` 被删除),在过渡/动画完成之后移除。

transition.png

<template>
  <div class="home">
    <button @click="show = !show">click</button>
    //使用组件
    <transition>
      <h1 v-if="show">this is home</h1>
    </transition>
  </div>
</template>

<script>
import "../assets/css/animate.css";
export default {
  name: "HomeView",
  data() {
    return {
      show: false,
    };
  },
};
</script>

<style lang="scss" scoped>
.v-enter,
.v-leave-to {
  opacity: 0;
}
.v-enter-to,
.v-leave {
  opacity: 1;
}
.v-enter-active,
.v-leave-active {
  transition: all 2s;
}
</style>

- [ 使用动画 ]

// 组件尾部的css样式更改
<style lang="scss" scoped>
.v-enter-active {
  animation: run 1s linear forwards;
}
.v-leave-active {
  animation: run 2s linear forwards reverse;
}

@keyframes run {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>

2、transition命名

使用name给动画命名

  <transition name="a">
  
  --------------------------------------
  //如果命名了 css中类名要改成a-   默认是V-
  .a-enter,
  .a-leave-to {
     opacity: 0;
  }

3、ransition别名 -class

他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,比如:和 Animate.css 结合使用十分有用。

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)
//使用方法
< transition enter-active-class="a" leave-active-class="b">
 //组件页面
 <transition enter-active-class="a" leave-active-class="b">
      <h1 v-if="show">this is home</h1>
</transition>

--------------------------------------
//组件页下面的css中
.a {
  animation: run 1s linear forwards;
}
.b {
  animation: run 2s linear forwards reverse;
}

4、动态name过渡

通过动态name属性实现动态过渡案例

  <template>
  <div class="page">
    <p>
      <button @click="switchTransName">switch transitionName</button>
    </p>
    //name写一个动态的 data里面定义tranName
    <transition :name="tranName">
      <div v-if="show" class="box">hello</div>
    </transition>
 
  </div>
</template>
 
<script>
  export default {
    name: 'HelloWorld',
    data() {
      return {
        tranName: 'tran',
        show: true,
      }
    },
    mounted() {
      this.setIntervalAni();
    },
    methods: {
      setIntervalAni() {
        let vm = this;
        setInterval(function () {
          vm.show = !vm.show;
        }, 1000)
      },
      switchTransName() {
       //三元表达式判断
        this.tranName === 'fade' ? this.tranName = 'tran' : this.tranName = 'fade';
      }
    }
  }
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
  .box {
    width: 100px;
    text-align: center;
  }
    
 //两套样式  fade的一套 tran的一套
    
  // fade
    
  .fade-enter {
    opacity: 0;
  }
 
  .fade-enter-active, .fade-leave-active {
    transition: all 0.5s;
  }
 
  .fade-leave-to {
    opacity: 0;
  }
 
  // tran
    
  .tran-enter {
    // transform: scaleX(3) scaleY(3);  =  transform: scale(3, 3);
    transform: scale(3, 3);
  }
  
  .tran-enter-active, .tran-leave-active {
    transform-origin: center;
    transition: all 1s;
  }
 
  .tran-leave-to {
    transform: scale(0, 0);
  }
</style>

5、animate.css动画库

安装:yarn add animate.css

引入: import "animate.css";

    <template>
  <div class="home">
    <button @click="show = !show">click</button>
    
    <transition
      enter-active-class="animate__animated animate__zoomIn"
      leave-active-class="animate__animated  animate__zoomOut"
    >
      <h1 v-if="show">this is home</h1>
    </transition>
      </div>
</template>
-----------
<script>
//引入动画库组件
  import "animate.css";
</script>

6、生命周期钩子

可以在 attribute 中声明 JavaScript 钩子

//钩子
<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
    //组件页面
<template>
  <div class="home">
    <button @click="show = !show">click</button>
    <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:after-enter="afterEnter"
      enter-active-class="animate__animated animate__zoomIn"
      leave-active-class="animate__animated  animate__zoomOut"
    >
      <h1 v-if="show">this is home</h1>
    </transition>
  </div>
</template>

<script>
//引入动画库组件
import "animate.css";
export default {
  name: "Animate",
  data() {
    return {
      show: false
    };
  },
  methods: {
      //开始准备进入动画状态
    beforeEnter(el) {
      console.log("进入前");
      el.style.color = "red";
    },
    //已经进入动画状态
    enter(el,done) {
      console.log("进入中");
      let timer = setInterval(() => {
        if (el.style.color == "red") el.style.color = "blue";
        else el.style.color='red'
      },1000);
      setTimeout(()=>{
          clearInterval(timer)
          //表示enter执行完毕,使用done方法执行afterEnter
          done()
      },5000)
    },
      //进入动画之后
    afterEnter(el){
        console.log('进入后');
        el.style.color='green'
    }
  }
};
</script>

<style lang="scss" scoped>
.v-enter-active {
  animation: run 1s linear forwards;
}
.v-leave-active {
  animation: run 2s linear forwards reverse;
}

@keyframes run {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>

7、组件过渡 :is

< h1 :is="componentId">this is home1

<template>
  <div class="home">
    <!-- <button @click="show = !show">click</button> -->
    <button @click="change">点击</button>
    <!-- out-in先出后进 -->
    <transition
      mode="in-out"
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:after-enter="afterEnter"
      enter-active-class="animate__animated animate__slideInLeft"
      leave-active-class="animate__animated  animate__slideOutRight"
    >
        //动态组件  is绑定
      <h1 :is="componentId">this is home1</h1>
    </transition>
  </div>
</template>

<script>
//引入动画库组件
import "animate.css";
import Demo1 from "../components/Demo1.vue";
import Demo2 from "../components/Demo2.vue";
export default {
  name: "Animate",
  components: { Demo1, Demo2 },
  data() {
    return {
      componentId: "Demo1"
    };
  },
  methods: {
    change() {
      if (this.componentId == "Demo1") this.componentId = "Demo2";
      else this.componentId = "Demo1";
    },
    //开始准备进入动画状态
    beforeEnter(el) {
      console.log("进入前");
      el.style.color = "red";
    },
    //已经进入动画状态
    enter(el, done) {
      console.log("进入中");
      let timer = setInterval(() => {
        if (el.style.color == "red") el.style.color = "blue";
        else el.style.color = "red";
      }, 3000);
      setTimeout(() => {
        clearInterval(timer);
        //表示enter执行完毕,使用done方法执行afterEnter
        done();
      }, 2000);
    },
    afterEnter(el) {
      console.log("进入后");
      el.style.color = "green";
    }
  }
};
</script>

8、列表过渡transition-group

  • 内部元素总是需要提供唯一的 key attribute 值。
  • CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。
  • 在有多个元素需要进行过渡时使用
  • 列表的排序过渡 ,加一个class类:v-move,页面不会duang一下
<template>
  <div class="home2">
    <div>
      ID:<input type="text" v-model="id" />
      <br />
      name: <input type="text" v-model="name" />
      <br />
      <button @click="push">push</button>
      <button @click="unshift">unshift</button>
    </div>
       <!-- transition会自动创建一个ul标签 -->
    <!-- appear初次渲染 -->
    <transition-group tag="ul" appear>
      <li
        v-for="(item, index) in users"
        :key="item.id"
        @click="del(index)"
        ref="li"
      >
        {{ item.id }}---{{ item.name }}
      </li>
    </transition-group>
  </div>
</template>

<script>
//引入动画库组件
import "animate.css";
export default {
  name: "HomeView",
  data() {
    return {
      id: "",
      name: "",
      users: [
        { id: 1, name: "jim" },
        { id: 2, name: "tom" },
      ],
    };
  },
  methods: {
    push() {
      this.users.push({
        id: this.id,
        name: this.name,
      });
    },
    unshift() {
      this.users.unshift({
        id: this.id,
        name: this.name,
      });
    },
    del(index) {
      this.users.splice(index, 1);
    },
  },
  mounted() {
    this.$refs.li.forEach((item, index) => {
      item.style = `transition-delay:${index * 200}ms`;
    });
  },
};
</script>


<style lang="scss" scoped>
li {
  background-color: skyblue;
  margin: 5px;
  line-height: 30px;
}
.v-enter,
.v-leave-to {
  opacity: 0;
  transform: translateX(-100%);
}
.v-enter-active,
.v-leave-active {
  transition: all 1s;
}

.v-enter-to,
.v-leave {
  opacity: 1;
  transform: translateX(0);
}
//v-move,页面不会duang一下
.v-move {
  transition: all 1s;
}
</style>

暂时完结!!!