h5移动端应用实现类似原生页面切换效果

1.原理

将vue-router中的跳转方法重写并监听,根据不同的跳转类型加载不同的过渡动画。

2.实现

创建router-helper.js文件

export const DirectionType = {
// 进入动画
In: 'in ',
// 退出动画
Out: 'out ',
/** 不应用动画,用于处理IOS侧滑冲突 */
None: ' '
}

// 路由动画
export const routeTransition = (router) => {
/** 默认认为是IOS的侧滑返回,通过监听router方法进行改变 */
let isIosJump = true
let direction = DirectionType.None

/** 处理路由跳转动画,push、replace、go(正值 | 0)应用In动画,其他情况应用Out动画 */ router.replace = inject( 'before ', router.replace, () => {
isIosJump = false
direction = DirectionType.In
})

router.push = inject( 'before ', router.push, () => {
isIosJump = false
direction = DirectionType.In
})

router.go = inject( 'before ', router.go, (delta) => {
isIosJump = false
if (delta >= 0) {
  direction = DirectionType.In
} else {
  direction = DirectionType.Out
}
})

router.back = inject( 'before ', router.back, () => {
isIosJump = false
direction = DirectionType.Out
})

router.beforeEach((to, from, next) => {
// 如果是IOS侧滑则不应用侧滑动效

if (isIosJump) {
  direction = DirectionType.None
}

to.meta.direction = direction

next()
})

router.afterEach(() => {
isIosJump = true
})
}

function inject(position, func, handler) {
return (...args) => {
if (position === 'before ' | | position === 'after ') handler === null | | handler === 0 ? 0 : handler(...args)
return func(...args)
}
}

在router.js中引入routeTransition方法

import { routeTransition } from './router-helper '
// 应用路由跳转动画
// 此处的router是通过createRouter 创建出来的路由实例
routeTransition(router)

创建计算路由切换方向的useDirection.js

import { computed } from 'vue '
import { useRoute } from 'vue-router '
import { DirectionType } from '@/router/router-helper '

export const useDirection = () => {
const route = useRoute()
const direction = computed(() => {
// 获取当前页面滑动动效方向,  "" 表示不应用动效,处理ios下动效冲突问题
if (route.meta.direction === DirectionType.None) return DirectionType.None
// 与动画名字保持一致
return 'page- ' + (route.meta.direction === DirectionType.In ? DirectionType.In : DirectionType.Out)
})
return direction
}

<template>
<router-view v-slot="{ Component }">
<transition :name="direction" :css="!!direction">
  <component :is="Component" />
</transition>
</router-view>
</template>
<script setup>
import { useDirection } from '@/hooks/useDirection '
const direction = useDirection()
</script>

过渡动画

.page-out-enter-active,
.page-out-leave-active,
.page-in-enter-active,
.page-in-leave-active {
will-change: transform;
transition: transform 0.25s ease-out;
height: 100%;
width: 100%;
top: 0;
left: 0;
position: fixed;
backface-visibility: hidden;
perspective: 1000;
background-color: #f4f4f4;
}

.page-out-enter-from {
transform: translateX(-30%);
}

.page-out-leave-active {
transform: translateX(100%);
z-index: 2;
}

.page-in-enter-from {
transform: translateX(100%);
}

.page-in-leave-active {
transform: translateX(-30%);
}

3.效果

在这里插入图片描述

作者:孟兵

猜你喜欢

转载自blog.csdn.net/ekcchina/article/details/129892576