vue页面切换项目实现转场动画的方法


Posted in Javascript onNovember 12, 2019

前言

移动端, 使用vue为了良好的用户体验, 会需要实现APP形式的切换页面的左滑和右滑效果

实现原理, vue的过渡 & 动画

技术栈: vue + vue-router

解决思路

区分前进 和 后退的路由

网上搜索的资料, 找到了两种

监听popstate事件

window.addEventListener('popstate', function (e) {
  // 用来判断是否是后退, 在判断后需要在其他地方重置
  router.isBack = true
},false)

在注册路由的时, 添加 meta对象 ( 路由元信息)中添加索引, 这样做就需要注意索引的大小(这里使用这一种方式)

{
   path: "/login",
   component: resolve => require(["@/pages/login"], resolve),
   meta: {
    title: "登录",
    keepAlive: false,
    index: 1
   }
  },
  {
   path: "/forward",
   name: "Forward",
   component: resolve => require(["@/pages/forward"], resolve),
   meta: {
    title: "前进",
    keepAlive: true,
    index: 2
   }
  },

根据切换方向设置不同的动画效果(通过给transtion内置组件不同的name选项)

方案

路由注册

{
   path: "/login",
   component: resolve => require(["@/pages/login"], resolve),
   meta: {
    title: "登录",
    keepAlive: false, // 用来判断是否缓存, 当判断为缓存时, 则路由信息的name和组件的name选项需一致
    index: 1, // 通过比较不同的索引, 来判断是前进动画还是后退动画
   }
  },
  {
   path: "/forward",
   name: "Forward",
   component: resolve => require(["@/pages/forward"], resolve),
   meta: {
    title: "前进",
    keepAlive: true,
    index: 2
   }
  },

在App.vue(根组件)中, 判断动画方向

<template>
 <div id="project">
   <!-- 
   <keep-alive>
       <router-view v-if="$route.meta.keepAlive"></router-view>
   </keep-alive>
   <router-view v-if="!$route.meta.keepAlive"></router-view>
   这种情况下, 
   :include: 因为若是使用transition包裹两个keep-alive, vue会出现报错
        用两个transition分别包裹keep-alive, 会让transition的动画name出现问题
 --> 
  <transition :name="transitionName">
   <keep-alive :include="cachedViews">
    <router-view :key="1"></router-view>
   </keep-alive>
  </transition>
 </div>
</template>

<script>
export default {
 name: "App",
 data() {
  return {
   transitionName: "slide-right", // 初始过渡动画方向
   cachedViews: [] // 缓存组件
  };
 },
 components: {},
 created() {},
 watch: {
  $route(to, from) {
   if (to.meta.keepAlive && !this.cachedViews.includes(to.name)) {
    // 将需要缓存的组件信息, 添加进其中, 其中to.name的值应该和匹配组件的name选项一致
    this.cachedViews.push(to.name);
   }
   //如果to索引大于from索引,判断为前进状态,反之则为后退状态
   if (to.meta.index > from.meta.index) {
    //设置动画名称
    this.transitionName = "slide-left";
   } else {
    this.transitionName = "slide-right";
   }
  }
 },
 methods: {}
};
</script>


<style lang="scss" scoped>
.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
 will-change: transform;
 transition: all 0.5s;
 <!-- 
  这个是必须的, 是为了让页面脱离文档流, 不然的话, 后进入的页面会从页面底部出来
  这个定位会直接添加到路由匹配的组件根元素上, 所以页面根组件最好设定其宽度为100vw
 -->
 width: 100vw;
 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>

待解决问题

  • 子路由问题

子路由还没有考虑到

  • 缓存组件问题

使用上述方式, 缓存组件需要注意组件的name选项要和路由的name选项一致, 容易疏忽填写组件的name选项问题

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery中filter(),not(),split()使用方法
Jul 06 Javascript
js 创建书签小工具之理论
Feb 25 Javascript
JavaScript中的style.display属性操作
Mar 27 Javascript
用js实现in_array的方法
Nov 05 Javascript
js特殊字符过滤的示例代码
Mar 05 Javascript
angularjs学习笔记之简单介绍
Sep 26 Javascript
Bootstrap实现带动画过渡的弹出框
Aug 09 Javascript
JavaScript模拟实现封装的三种方式及写法区别
Oct 27 Javascript
jquery根据name取得select选中的值实例(超简单)
Jan 25 jQuery
对Angular中单向数据流的深入理解
Mar 31 Javascript
vue动态禁用控件绑定disable的例子
Oct 28 Javascript
js实现弹幕墙效果
Dec 10 Javascript
解决vue-cli 打包后自定义动画未执行的问题
Nov 12 #Javascript
vue transition 在子组件中失效的解决
Nov 12 #Javascript
vue+element导航栏高亮显示的解决方式
Nov 12 #Javascript
vue-element-admin 菜单标签失效的解决方式
Nov 12 #Javascript
Vue退出登录时清空缓存的实现
Nov 12 #Javascript
解决vue admin element noCache设置无效的问题
Nov 12 #Javascript
Vue2.0 实现页面缓存和不缓存的方式
Nov 12 #Javascript
You might like
整合了前面的PHP数据库连接类~~做成一个分页类!
2006/11/25 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
php htmlspecialchars()与shtmlspecialchars()函数的深入分析
2013/06/05 PHP
PHP中的静态变量及static静态变量使用详解
2015/11/05 PHP
thinkphp5框架扩展redis类方法示例
2019/05/06 PHP
php实现JWT验证的实例教程
2020/11/26 PHP
js自动闭合html标签(自动补全html标记)
2012/10/04 Javascript
IE6已终止操作问题的2种情况及解决
2014/04/23 Javascript
javascript将url中的参数加密解密代码
2014/11/17 Javascript
JavaScript中的数值范围介绍
2014/12/29 Javascript
JavaScript动态添加style节点的方法
2015/06/09 Javascript
使用堆实现Top K算法(JS实现)
2015/12/25 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
2016/04/17 Javascript
微信小程序 POST请求(网络请求)详解及实例代码
2016/11/16 Javascript
ES6之模版字符串的具体使用
2018/05/17 Javascript
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
利用Python实现在同一网络中的本地文件共享方法
2018/06/04 Python
Python实现网站表单提交和模板
2019/01/15 Python
如何在Django中添加没有微秒的 DateTimeField 属性详解
2019/01/30 Python
TensorFlow实现简单的CNN的方法
2019/07/18 Python
Python基于OpenCV实现人脸检测并保存
2019/07/23 Python
python实现把两个二维array叠加成三维array示例
2019/11/29 Python
python实现控制台输出彩色字体
2020/04/05 Python
Python数据模型与Python对象模型的相关总结
2021/01/26 Python
python正则表达式re.match()匹配多个字符方法的实现
2021/01/27 Python
Python 里最强的地图绘制神器
2021/03/01 Python
商务主管岗位职责
2013/12/08 职场文书
退休感言
2014/01/28 职场文书
无偿献血倡议书
2014/04/14 职场文书
倡议书范文
2014/04/16 职场文书
ktv筹备计划书
2014/05/03 职场文书
政府信息公开实施方案
2014/05/09 职场文书
优秀教师事迹材料
2014/12/15 职场文书
小学四年级班务总结该怎么写?
2019/08/16 职场文书
动画电影《龙珠超 超级英雄》延期上映
2022/03/20 日漫
微信告警的zabbix监控系统 监控整个NGINX集群
2022/04/18 Servers