个人文档
  • AI编程Cursor
  • GPT使用笔记
  • npm常用库合集
  • 同步用
  • 小Demo们
  • 工具网站教程集合
  • HTML、CSS 工具方法集合
    • HTML 全局属性
    • css常用功能
    • font-face 字体|子集相关
    • iframe父子页面传值
    • input输入优化
    • loading状态
    • nodejs使用谷歌邮箱发邮件
    • 为 Dom 自定义事件监听
    • 初始html的head标签配置
    • 拼音输入中文汉字的事件监听
    • 文字颜色效果
    • 文档片段范围 Range
    • 移动端开发-rem
    • 等宽字体推荐
    • 网站SEO优化注意点
    • 邮件html模板
  • JS 工具方法集合
    • Axios 简单使用
    • Axios 简单封装
    • Gitbook的安装和使用
    • Github 登录开发
    • HTML转为纯文本
    • JS 中强大的操作符
    • cookie 操作
    • js 动态加载js资源
    • js 常用功能语句
    • js取代trycatch的方法封装
    • js接口下载二进制
    • script 标签的异步属性
    • 判断当前是移动端还是pc端
    • 刷新token队列管理
    • 前端多线程 Web Worker
    • 加密-AES对称加密
    • 加密-node进行rsa加密解密
    • 地区省市区三级联动的地址数据 + 功能
    • 复制插件
    • 开发时环境变量
    • 得到随机图片
    • 数字格式整理集合
    • 数学计算插件
    • 时间格式整理
    • 获取ip地址
    • 获取url传参
    • 进制转换和位运算符
    • 页面隐藏|激活|关闭的监听
  • JS 知识点研究
    • Babel 历史和原理
    • Babel 配置和使用
    • Function 的 apply、call、bind
    • HTTP浏览器缓存粗解
    • Source map 文件还原为源码
    • TS常用技巧
    • js 的加载和模块化
    • js 的新数据类型 Symbol
    • js的代理对象 proxy 和 defineProperty
    • js的原型链 prototype
    • vite 打包体积优化
    • webpack 可视化打包文件大小插件
    • webpack 基础使用配置
    • webpack 版本5的报错
    • yeoman 开发脚手架的工具
    • 同步异步和微任务宏任务
    • 移动端调试---谷歌工具+eruda+vconsole
    • 转换-Blob URL
    • 转换-FileReader
    • 转换-Js文件类型和转换
    • 转换-前端开发的URL的编码和解码
    • 转换-字符串和Base 64的转换
  • Node 和 Npm 相关
    • Node 开发环境配置
    • express + jwt 校验
    • node 常用方法
    • node后台服务器-PM2
    • node基本使用
    • npm 中依赖的版本问题
    • npm 功能使用
    • npm指令说明和其他对比
    • nvm版本管理+自动切换node版本
  • React 学习
    • React Hook
    • React 项目基础开发
    • React.memo 和 React.PureComponent
    • React懒加载进阶
    • useContext Hook
    • useEffect Hook
    • useMemo 和 useCallback - Hook
    • useRef Hook
    • useState Hook
    • 同步修改变量功能封装 useVal for react
    • 轻便的传值组件
  • Rust 语言相关
    • Rust 基本
    • Rust 基础学习
    • Rust 调用 Object-C 的API
    • Tauri 基本使用
    • Tauri 是什么
  • VUE 学习
    • Vue3 使用
    • Vue3使用hook
    • Vue开发小技术点
    • vue路由切换时的动画效果
    • 花式引入组件和资源-打包时拆包减少js体积
  • Web3相关
    • Web3.0开发上-准备和概念理解
    • Web3.0开发下-功能代码示例
    • 以太坊区块链和Web3.0
    • 开发智能合约
  • python
    • pyenv版本管理工具
    • python初始化
    • python基本概念
    • venv虚拟环境
  • 个人其他
    • Steam Deck的基本设置和插件
  • 其他编程相关
    • Git教程和常用命令
    • Java开发-JDK和Maven的安装和卸载
    • Jenkins安装和基本使用
    • Linux系统指令
    • Mac 使用2K屏幕开启缩放
    • Mac 使用VS code打开项目
    • Mac 安装 Homebrew
    • Mac 的终端 shell 与 zsh
    • Mac 软件和插件
    • MacBook使用建议
    • Mac升降级到指定版本的系统
    • Mac安装Zsh
    • Mac安装软件各种提示
    • Mac系统脚本语言 AppleScript 的使用
    • Mac终端代理工具
    • Markdown(md)文档开发-Typora
    • Mysql 的安装和使用
    • Nginx 安装和基础使用
    • Nginx 稍微高深的配置
    • Slate - Api 的文档开发工具
    • Sublime配置
    • Ubuntu的 apt-get 使用
    • VScode配置
    • Windows 软件和插件
    • curl 工具使用
    • github 网站访问优化
    • host 文件
    • inquirer 终端中和用户交互
    • uTools的插件开发教程
    • vim 文本编辑功能
    • 使用 Github Pages 免费部署网站
    • 压缩指令 zip 和 unzip
    • 油猴的安装和开发(Tampermonkey)
    • 阿里云简略使用
  • 微信开发
    • 微信小程序开发
    • 微信开发必读
    • 微信开发提前购买域名
    • 微信手机打开的页面中授权登录
    • 微信扫码登录
    • 微信服务号登录+推送服务提醒
    • 自定义分享卡片-node.js实现
  • 数据结构与算法
    • KMP算法
    • Wildcard字符串分析算法
    • 二叉树
    • 字典树
    • 时间复杂度浅析
    • 算法神器——动态规划
Powered by GitBook
On this page

Was this helpful?

  1. VUE 学习

vue路由切换时的动画效果

title: vue路由切换时的动画效果 id: 8a8d3844de849da54a6af3da6edac113 tags:

  • 代码片段

  • vue date: 2024/09/12 18:25:44 updated: 2024/09/12 18:25:44 isPublic: true --#|[分隔]|#--

vue路由切换时的动画效果

使用vue开发页面,经常有需求想要在切换页面时添加一个动画效果,尤其移动端,切换页面时,希望新页面能从右边覆盖过来,返回上一页时,又是前一页从左边覆盖过来。

这里vue的自带组件Transition来调一下。

技术栈:vue3 + ts

官方Transition文档:https://cn.vuejs.org/guide/built-ins/transition

效果:

  • 点击打开下一页时,新页面从右侧覆盖过来,原页面会向左偏移一些,最终被覆盖掉。

  • 返回上一页时,上一个页面从左侧覆盖过来,原页面会向右偏移一些,最终被覆盖掉。

  • 使用router.replace()方法替换当前页面时,不执行动画。

注意点:

  • 需要使用全局状态记录当前是前进、回退页面,因为这个状态的修改和使用,是在不同文件中发生的。

  • 需要自行记录当前打开过的页面历史作为一个数组,以便能判断是否是返回下一页,如果是返回上一页或者替换,需要处理这个数组。

  • 所有的页面文件的 template 标签中的标签,需要使用单独的一个标签包裹,这一点详细在本文档底部说明。

1. 新建一个pinia的store

这个文件的作用存储全局变量,来维护当前的状态,来确定当前是否是不使用动画、是前进页面、是回退页面。

新建文件 src/stores/pageTransition.ts 内容:

import { defineStore } from 'pinia';

type Type = '' | 'prev' | 'next'

export const usePageTransition = defineStore('usePageTransition', {
	state: () => ({
		changeType: '' as Type, // 页面跳转的方向,是返回,还是前进,对应不同的动画
	}),
	getters: {
		// 获取Transition的name
		pageTransitionName(state) {
			if (state.changeType === 'prev') return 'page-prev'
			else if (state.changeType === 'next') return 'page-next'
		},
	},
	actions: {
		changePageType(newVal: Type) {
			this.changeType = newVal
		},
	},
})

2. 修改路由配置文件

修改路由配置文件,这个文件一般是 src/router/index.ts。

这个文件中:

  1. 需要创建 routeStack 数组,记录的已打开过页面的路由栈。

  2. 创建 isReplace 变量,用来记录「当前是否是替换页面」,然后重写 router.replace 方法,在这里面把 isReplace 改为 true,然后再真的去调用 vue-router 的替换页面的 Api。

  3. 在 router.beforeEach 路由守卫中添加代码,主要功能是:判断当前是替换页面、返回上一页还是正常跳新页面,然后修改全局变量 src/stores/pageTransition.ts 中的值。

import { usePageTransition } from '@/stores/pageTransition';
import * as VueRouter from 'vue-router'

let router = VueRouter.createRouter({
  // history: VueRouter.createWebHashHistory(),
  history: VueRouter.createWebHistory(),
  routes: [
    // 路由信息们
  ],
})

// 记录的已打开过页面的路由栈
let routeStack: VueRouter.RouteLocationNormalizedGeneric[] = []
let isReplace = false // 是否是替换页面跳转的

// 扩展 Vue Router 实例,以便在每次调用 replace 方法时添加一个标志
const originalReplace = router.replace.bind(router);
router.replace = ((location: string) => {
  isReplace = true
  originalReplace(location)
}) as typeof router.replace

router.beforeEach((to, from) => {
  usePageTransition().changePageType('')
  // 是替换页面
  if (isReplace) {
    routeStack.pop()
    routeStack.push(to)
    isReplace = false
  } else if (routeStack[routeStack.length - 2]?.path === to.path) {
    // 发现实际是返回上一页
    routeStack.splice(routeStack.length - 2, 2)
    routeStack.push(to)
    // 设置路由动画为返回
    usePageTransition().changePageType('prev')
  } else {
    routeStack.push(to)
    // 设置路由动画为前进
    usePageTransition().changePageType('next')
  }
  return true
})

export default router

3. App.vue中配置动画

使用 Transition 组件,并在 style 中添加动画。

  • Transition 组件的 name 属性,需要取全局状态的记录值,值可能为 '' | 'prev' | 'next'。

  • 添加 Transition 组件添加 @after-leave 事件监听,也就是切换页面完成后,需要重置全局状态的记录值。

  • Transition 的执行动画时的名称,是基于 name 属性拼接的,所以在 style 中配置动画时,需要分别配置好。

<template>
  <router-view #default="{ Component }">
    <Transition @after-leave="usePageTransition().changePageType('')" :name="usePageTransition().pageTransitionName">
      <keep-alive>
        <component :is="Component" />
      </keep-alive>
    </Transition>
  </router-view>
  {{ usePageTransition().pageTransitionName }}
</template>

<script lang="ts" setup>
import { usePageTransition } from '@/stores/pageTransition';
</script>

<style lang="scss" scoped>
.page-prev-enter-active, .page-prev-leave-active,
.page-next-enter-active, .page-next-leave-active {
  transition: all 1s;
  position: fixed;
  overflow: hidden;
  width: 100vw;
  left: 0;
  top: 0;
  background: white;
}
.page-prev-enter-active, .page-next-enter-active {
  z-index: 2;
}
.page-prev-leave-active, .page-next-leave-active {
  z-index: 1;
}
.page-prev-enter-from {
  transform: translateX(-100vw);
}
.page-next-enter-from {
  transform: translateX(100vw);
}
.page-next-leave-to {
  transform: translateX(-50vw);
}
.page-prev-leave-to {
  transform: translateX(50vw);
}
</style>

至此,完成。

补充:页面文件的 template 标签中的写法

本来,vue3的组件中是可以这么写的:

<template>
  <div>第一行</div>
  <div>第二行</div>
  一些其他文本
</template>

但如果要使用这个页面切换效果,就不可以了,必须使用一个标签把他们都包裹起来。

因为上面第3步中的style中使用的那个类名,是直接添加到这个页面组件上面,这个组件的html代码的顶层必须是一个可以承接类名class属性的标签。

修改后的写法:

<template>
  <div>
    <div>第一行</div>
    <div>第二行</div>
    一些其他文本
  </div>
</template>
PreviousVue开发小技术点Next花式引入组件和资源-打包时拆包减少js体积

Last updated 3 months ago

Was this helpful?