vue: 动画的应用(二)

文档: cn.vuejs.org/v2/guide/t

八个钩子函数:

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="leaveCancelle 离开中取消

:css="false": 告诉vue这是js纯动画,不需要查找css,节省性能

name="slide": 结合css使用,js主要负责逻辑操作

        <template>
  <div>
    <p>{{ load }}</p>
    <hr>
    <button class="btn btn-primary" @click="load = !load">点击</button>
    <transition
      @before-enter = "beforeEnter"
      @enter = "enter"
      @after-enter = "afterEnter"
      @enter-cancelled = "enterCancelled"
 
      @before-leave = "beforeLeave"
      @leave = "leave"
      @after-leave = "afterLeave"
      @leave-cancelled = "leaveCancelled"
      :css="false">
      <div v-if="load" style="width: 100px; height: 15px; background-color : #eaff56; border-radius : 0 10px 10px 0;"></div>
    </transition>
  </div>
</template>

<script>

export default {
 data() {
 return {
      load : false,
      divWidth: 0,
    }
  },
  methods: {
 beforeEnter(el) {
 // console.log("beforeEnter")
 this.divWidth = 0;
 el.style.width = this.divWidth + "px";
    },
 enter(el, done) {
 // console.log("enter")
 // done()
 // done是个函数 执行完才会进行下一步
 let round = 1;
 const timer = setInterval( () => {
 el.style.width = (this.divWidth + round * 10) + "px";
        round++;
 // console.log(round)
 if(round > 50) {
 clearInterval(timer);
 done();
        }
      },20 )
    },
 afterEnter(el) {
 // console.log("afterEnter")
 el.style.width = "500px"
    },
 enterCancelled(el) {
 console.log("enterCancelled")
 // 动画取消的时候执行
 // 比如还没淡入完成就开始淡出的时候
 // 可以直接写在css上
    },
 beforeLeave(el) {
 // console.log("beforLeave")
 el.style.width = "500px";
 this.divWidth = 500;
    },
 leave(el, done) {
 // console.log("leave")
 // done()
 let round = 1;
 const timer = setInterval( () => {
 el.style.width = (this.divWidth - round * 10) + "px";
        round++;
 // console.log(round)
 if(round > 50) {
 clearInterval(timer);
 done();
        }
      },20 )
    },
 afterLeave(el) {
 // console.log("afterLeave")
 this.divWidth = 0;
    },
 leaveCancelled(el) {
 // console.log("leaveCancelled")
    }
  }
}
</script>

<style>

</style>


      

v2-cd2bc998dfd3ca00382f12ddc033c3d2_b.gif

切换组件的动画

动态切换组件动画

使用一个button按钮来控制组件的切换,使用:is绑定动态的组件,使用transition来做就可以了

我引入来animation库

        <template>
  <div>
    <p>{{ load }}</p>
    <hr />
    <button class="btn btn-primary" @click="load = !load">点击</button>
    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"
      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
      :css="false"
    >
      <div
 v-if="load"
 style="width: 100px; height: 15px; background-color : #eaff56; border-radius : 0 10px 10px 0;"
      ></div>
    </transition>
    <hr>
    <button class="btn btn-primary" @click=" selectComponent == 'app-alert-danger' ? selectComponent = 'app-alert-success' : selectComponent = 'app-alert-danger'">切换组件</button>
    <br><br>
    <transition 
 enter-active-class="animated rollIn"
 leave-active-class="animated rollOut"
 mode="out-in">
      <component :is="selectComponent"></component>
    </transition>
  </div>
</template>

<script>
import alertDanger from "./alertDanger"
import alertSuccess from "./alertSuccess"
export default {
 data() {
 return {
      load: false,
      divWidth: 0,
      selectComponent: "app-alert-danger"
    };
  },
  components: {
 "app-alert-danger" : alertDanger,
 "app-alert-success" : alertSuccess,
 // 带上-,防止第三方库冲突
  },
  methods: {
 beforeEnter(el) {
 // console.log("beforeEnter")
 this.divWidth = 0;
 el.style.width = this.divWidth + "px";
    },
 enter(el, done) {
 // console.log("enter")
 // done()
 // done是个函数 执行完才会进行下一步
 let round = 1;
 const timer = setInterval(() => {
 el.style.width = this.divWidth + round * 10 + "px";
        round++;
 // console.log(round)
 if (round > 50) {
 clearInterval(timer);
 done();
        }
      }, 20);
    },
 afterEnter(el) {
 // console.log("afterEnter")
 el.style.width = "500px";
    },
 enterCancelled(el) {
 console.log("enterCancelled");
 // 动画取消的时候执行
 // 比如还没淡入完成就开始淡出的时候
 // 可以直接写在css上
    },
 beforeLeave(el) {
 // console.log("beforLeave")
 el.style.width = "500px";
 this.divWidth = 500;
    },
 leave(el, done) {
 // console.log("leave")
 // done()
 let round = 1;
 const timer = setInterval(() => {
 el.style.width = this.divWidth - round * 10 + "px";
        round++;
 // console.log(round)
 if (round > 50) {
 clearInterval(timer);
 done();
        }
      }, 20);
    },
 afterLeave(el) {
 // console.log("afterLeave")
 this.divWidth = 0;
    },
 leaveCancelled(el) {
 // console.log("leaveCancelled")
    }
  }
};
</script>

<style>
</style>


      

v2-519958d9a36d7550e4279b0eadde647a_b.gif



需求: 做一个动画的列表过渡

transition-group

要求: 做一个按钮,点击按钮在列表中随机添加一个数,点击列表中的li,删除该li

transition-group和transition的区别:

transition-group会生成一个真实的dom,默认span,可以使用tag属性来修改,还可以添加class;

transition不会;

transition-group需要key值才能用

        <template>
  <div>
    <p>{{ load }}</p>
    <hr />
    <button class="btn btn-primary" @click="load = !load">点击</button>
    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"
      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
      :css="false"
    >
      <div
 v-if="load"
 style="width: 100px; height: 15px; background-color : #eaff56; border-radius : 0 10px 10px 0;"
      ></div>
    </transition>
    <hr>
    <button class="btn btn-primary" @click=" selectComponent == 'app-alert-danger' ? selectComponent = 'app-alert-success' : selectComponent = 'app-alert-danger'">切换组件</button>
    <br><br>
    <transition 
 enter-active-class="animated rollIn"
 leave-active-class="animated rollOut"
 mode="out-in">
      <component :is="selectComponent"></component>
    </transition>
    <br><br>
    <hr>
    <button class="btn btn-primary" @click="addItem">添加列表</button>
    <transition-group tag="ul" class="list-group" name="slide">
      <li class="list-group-item" 
 v-for="(list, index) in lists" 
        @click="removeItem(index)" 
 style="cursor: pointer"
        :key="list">
        {{ list }}</li>
    </transition-group>
    <ul class="list-group">
 
    </ul>
  </div>
</template>

<script>
import alertDanger from "./alertDanger"
import alertSuccess from "./alertSuccess"
export default {
 data() {
 return {
      load: false,
      divWidth: 0,
      selectComponent: "app-alert-danger",
      lists: [1, 2, 3, 4, 5]
    };
  },
  components: {
 "app-alert-danger" : alertDanger,
 "app-alert-success" : alertSuccess,
 // 带上-,防止第三方库冲突
  },
  methods: {
 addItem() {
 const pos = Math.floor(Math.random() * this.lists.length);
 // 在当前列表中随机找一个行前添加
 this.lists.splice(pos, 0, this.lists.length + 1)
 // 在列表中有几个数,就添加比几个数多1的数
    },
 removeItem(index) {
 this.lists.splice(index, 1)
 // 切割1项
    },
 beforeEnter(el) {
 // console.log("beforeEnter")
 this.divWidth = 0;
 el.style.width = this.divWidth + "px";
    },
 enter(el, done) {
 // console.log("enter")
 // done()
 // done是个函数 执行完才会进行下一步
 let round = 1;
 const timer = setInterval(() => {
 el.style.width = this.divWidth + round * 10 + "px";
        round++;
 // console.log(round)
 if (round > 50) {
 clearInterval(timer);
 done();
        }
      }, 20);
    },
 afterEnter(el) {
 // console.log("afterEnter")
 el.style.width = "500px";
    },
 enterCancelled(el) {
 console.log("enterCancelled");
 // 动画取消的时候执行
 // 比如还没淡入完成就开始淡出的时候
 // 可以直接写在css上
    },
 beforeLeave(el) {
 // console.log("beforLeave")
 el.style.width = "500px";
 this.divWidth = 500;
    },
 leave(el, done) {
 // console.log("leave")
 // done()
 let round = 1;
 const timer = setInterval(() => {
 el.style.width = this.divWidth - round * 10 + "px";
        round++;
 // console.log(round)
 if (round > 50) {
 clearInterval(timer);
 done();
        }
      }, 20);
    },
 afterLeave(el) {
 // console.log("afterLeave")
 this.divWidth = 0;
    },
 leaveCancelled(el) {
 // console.log("leaveCancelled")
    }
  }
};
</script>

<style>
 .slide-enter {
 opacity: 0;
 transform: translateY(20px)
  }
 .slide-enter-active {
 transition: opacity 1s;
 animation: slide-in 1s ease-out;
  }
 .slide-enter-to {
 transform: translateY(0px)
  }
 .slide-leave {
 transform: translateY(0px)
  }
 .slide-move {
 transition: transform 1s;
  }
 .slide-leave-active {
 transition: opacity 1s;
 animation: slide-out 1s ease-out;
 position: absolute;
 /* 离开的时候脱离文档流 */
  }
 .slide-leave-to {
 opacity: 0;
 transform: translateY(20px)
  }
 /* 进入轨迹 */
 @keyframes slide-in {
    from{
 transform: translateY(20px);
    }
    to{
 transform:  translateY(0);
    }
  }
 /* 离开轨迹 */
 @keyframes slide-out {
    from{
 transform:  translateY(0);
    }
    to{
 transform:  translateY(20px);
    }
  }
</style>


      

v2-2891de7849177c66cc5bdb5bcaf2fbc9_b.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值