当前位置: 首页 > news >正文

Vue 新手学习笔记:动画效果

1.过渡类名实现动画

参考:单元素/组件的过渡

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

  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 被删除),在过渡/动画完成之后移除。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    /* v-enter 是元素进入的起始状态,此时还没进入 */
    /* v-leave-to 是动画离开之后,离开的终止状态,此时元素动画已经结束 */
    .v-enter,.v-leave-to{
      opacity: 0;
      /* x 轴偏移 150px */
      transform: translateX(150px)
    }
    /* v-enter-active 是入场动画的时间段 */
    /* v-leave-active 是离场动画的时间段 */
    .v-enter-active,
    .v-leave-active{
      /* all 表示所有元素,0.8s 是持续时间,ease 是动画效果 */
      transition: all 0.8s ease;
    }

    /* 自定义 */
    .my-enter,.my-leave-to{
      opacity: 0;
      transform: translateY(200px)
    }
    .my-enter-active,
    .my-leave-active{
      transition: all 0.8s ease;
    }
  </style>
</head>

<body>
  <div id="app">
    <input type="button" value="动画" @click="flag=!flag">
    <!-- 需求:点击按钮,让h3显示,再点击让h3隐藏 -->
    <!-- 1.使用 tansition 元素,把需要被动画控制的元素包起来 -->
    <!-- transition 是 Vue 官方提供的 -->
    <transition>
      <h3 v-if="flag">这是一个H3</h3>
    </transition>

    <hr>

    <!-- 自定义 transition 名字 -->
    <input type="button" value="动画" @click="flag2=!flag2">
    <transition name="my">
      <h1 v-if="flag2">这是一个H1</h1>
    </transition>
  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
        flag2: false,
      },
      methods: {},
    })
  </script>
</body>

</html>

 

2.通过引入第三方类库来实现动画

  1. 通过对应特性来引入第三方类库
    参考:自定义过渡的类名
  2. 通过 :duration 来设定效果持续的时间

这里以 Animate 为例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <link rel="stylesheet" href="./lib/animate.css">
</head>

<body>
  <div id="app">
    <input type="button" value="动画" @click="flag=!flag">
    <!-- <transition enter-active-class="animated bounceIn" 
      leave-active-class="animated bounceOut">
      <h1 v-if="flag">这是一个H1</h1>
    </transition> -->

    <!-- :duration 可以放在 transition 上,也可以放在标签上 -->
    <!-- 使用 :duration="毫秒值" 来统一设置入场和离场时候的动画时长 -->
    <!-- <transition enter-active-class="bounceIn" 
      leave-active-class="bounceOut" :duration="200">
      <h1 v-if="flag" class="animated">这是一个H1</h1>
    </transition> -->

    <!-- 通过传入对象,分别设置入场的时长和离场的时长 -->
    <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{ enter:200, leave:800 }">
      <h1 v-if="flag" class="animated">这是一个H1</h1>
    </transition>

  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
      },
      methods: {},
    })
  </script>
</body>

</html>

 

3.使用钩子函数来实现动画

使用上面的两种方式,都只能够实现整场动画,我也奇怪,所以我试过在上面的函数中把后半场动画的函数去掉,比如上面 2 中 这个H1 动画,当我把后半场动画的代码去掉后,第一次点击出现了前半场动画效果,然后第二次点击,文字消失,第三次点击才会再次出现动画效果,所以为了实现半场动画效果就有了钩子函数来实现

钩子函数参考:JavaScript 钩子

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <link rel="stylesheet" href="./lib/animate.css">
  <style>
    .ball{
      width: 15px;
      height: 15px;
      border-radius: 50px;
      background-color: red;
    }
  </style>
</head>

<body>
  <div id="app">
    <input type="button" value="快到碗里来" @click="flag=!flag">
    <!-- 使用 transition 把 div 包起来 -->
    <transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter">
        <div class="ball" v-show="flag"></div>
    </transition>
  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
      },
      methods: {
        //注意:钩子函数的第一个参数 el 表示要执行动画的那个元素,是个原生的 JS DOM 对象
        //可以认为, el 是通过 document.getElementById('') 方式获取的原生的 JS DOM 对象
        beforeEnter(el) {
          //表示动画入场之前,此时动画尚未开始,可以设置元素开始动画之前的起始样式
          //设置小球开始动画之前的起始位置
          el.style.transform = "translate(0, 0)"
        },
        enter(el, done) {
          //这句话,没有实际的作用,但是如果不写,出不来动画效果
          //可以认为 el.offsetWidth 会强制动画刷新
          el.offsetWidth;
          //表示动画开始之后的样式,这里可以设置小球完成动画之后的结束状态
          el.style.transform = "translate(150px, 450px)";
          el.style.transition = 'all 1s ease';

          //这里的 done,其实就是 afterEnter 函数,也就是说:done 是 afterEnter 函数的引用 
          done();
        },
        afterEnter(el) {
          //动画完成之后调用
          this.flag=!this.flag;
        }
      },
    })
  </script>
</body>

</html>

4.实现列表的动画效果

  1. 在需要使用列表过渡时候,如果过渡的元素是使用 v-for 循环出来的时候,应该使用 transition-group 代替 transition

  2. 在实现列表移除的效果时候,可以通过 .v-move 和 v-leave-active 配合使用,能够实现列表后续的动画元素

  3. 给 transition-group 添加 appear 可以添加页面刚展示出来的时候的入场效果

  4. 使用为 transition-group 设置 tag 属性,指定 transition-group 渲染为某个元素,如果不设置,默认渲染为 span 元素
    比如下面代码中,如果不使用 tag 属性,而是直接使用 ul 标签,那么在生成的列表中 ul 与 li 元素中间会多一层 span 标签,不符合 W3C 规范,也可能影响到代码的书写,甚至使用

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    li {
      border: 1px dashed #999;
      margin: 5px;
      line-height: 35px;
      padding-left: 5px;
      font-size: 12px;
      width: 100%;
    }

    li:hover {
      background-color: gold;
      transition: all 1s ease;
    }
  
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateY(80px)
    }
  
    .v-enter-active,
    .v-leave-active {
      transition: all 1s ease;
    }

    /* 下面的 .v-move 和 v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */
    .v-move{
      transition: all 1s ease;
    }
    .v-leave-active  {
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="app">
    <div>
      <label>
        Id:
        <input type="text" v-model="id">
      </label>
      <label>
        Name:
        <input type="text" v-model="name">
      </label>
      <input type="button" value="添加" @click="add">
    </div>
    <!-- <ul> -->
      <!-- 在需要使用列表过渡时候,如果过渡的元素是使用 v-for 循环出来的,则不能使用 transition -->
      <!-- 应该使用 transition-group -->
      <!-- 给 transition-group 添加 appear 可以添加页面刚展示出来的时候的入场效果 -->
      <!-- 使用为 transition-group 设置 tag 属性,指定 transition-group 渲染为某个元素,如果不设置,默认渲染为 span 元素 -->
      <transition-group appear tag="ul">
        <li v-for="(item,i) in list" :key="item.id" @click="del(i)">
          {{ item.id }}----{{ item.name }}
        </li>
      </transition-group>
    <!-- </ul> -->
  </div>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        id: '',
        name: '',
        list: [{
          id: 1,
          name: '宝马'
        }, {
          id: 2,
          name: '奔驰'
        }, {
          id: 3,
          name: '玛莎拉蒂'
        }, {
          id: 4,
          name: '五菱宏光'
        }],
      },
      methods: {
        add() {
          this.list.push({
            id: this.id,
            name: this.name
          });
          this.id = this.name = '';
        },
        del(i){
          this.list.splice(i,1);
        },
      },
    })
  </script>
</body>

</html>

 

相关文章:

  • Gitlab 之 命令行提交代码到 git
  • Ant 安装,配置文件编写与使用
  • 关于 sql server 用 IDEA 一直连不上的问题
  • maven 手动导入 jar 包
  • linux下node的安装以及环境配置
  • linux 文件压缩与解压
  • Docker 上部署 Nginx
  • Vue 新手学习笔记:vue-element-admin 之入门开发教程(v4.0.0 之前)
  • Gitlab Root 密码忘记了,修改密码
  • 打开,关闭,查看端口情况
  • Vue table 点击按钮展开折叠面板
  • Vue table 表格中参数过长省略并且提示显示
  • SpringBoot 第三方 jar 包及 xml 扫描问题
  • Java redirect 后台带参重定向到另一个接口
  • Vue 新手学习笔记:vue-element-admin 之登陆及目录权限控制
  • Android开源项目规范总结
  • axios 和 cookie 的那些事
  • css布局,左右固定中间自适应实现
  • CSS相对定位
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Python利用正则抓取网页内容保存到本地
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • 回顾2016
  • 算法-图和图算法
  • 一道面试题引发的“血案”
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • zabbix3.2监控linux磁盘IO
  • #微信小程序:微信小程序常见的配置传值
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (十一)手动添加用户和文件的特殊权限
  • (一)Java算法:二分查找
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)JAVA中的堆栈
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • ***检测工具之RKHunter AIDE
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net MVC中使用angularJs刷新页面数据列表
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • .sdf和.msp文件读取
  • @Async注解的坑,小心
  • @Mapper作用
  • @基于大模型的旅游路线推荐方案
  • [CISCN 2023 初赛]go_session
  • [FFmpeg学习]从视频中获取图片
  • [GXYCTF2019]BabyUpload1 -- 题目分析与详解
  • [hdu 3065] 病毒侵袭持续中 [AC自动机] [病毒特征码匹配]
  • [leetcode] 103. 二叉树的锯齿形层次遍历
  • [LeetCode]Reverse Linked List II
  • [Linux] LVS+Keepalived高可用集群部署
  • [Linux]使用CentOS镜像与rpm来安装虚拟机软件
  • [loj#115] 无源汇有上下界可行流 网络流