vue模拟原生页面跳转的最优解决方案

为实现APP内嵌H5开发页面与原生页面实现同样的跳转效果,我们利用Vue 提供了 <transition> 组件在单页面应用下来模拟原生的页面跳转。

因为项目需要用<keep-alive> 包裹缓存不活动的组件实例,所以原有App.vue中代码是这样的:

<template>
  <div id="app">
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive" />
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive" />
  </div>
</template>

这里我们需要使用<transition-group>标签进行包裹,并且为它的子元素设置上key

<template>
  <div id="app">
    <transition-group :name="transitionName">
      <div key="keepAlive" v-show="$route.meta.keepAlive">
        <keep-alive>
          <router-view v-if="$route.meta.keepAlive" />
        </keep-alive>
      </div>
      <router-view v-if="!$route.meta.keepAlive" :key="$route.name" />
    </transition-group>
  </div>
</template>

然后,我们为<transition>标签设置动态的name,通过监听route的变化,判断页面的前进或后退从而动态设置name的值,来改变页面的滑入滑出效果,这里我们需要提前在路由中定义每个页面的路由深度,以便在route变化时进行页面前进或后退的判断,路由深度定义:

const routes = [
    {
    path: "/reservationList",
    name: "reservationList",
    meta: {
      keepAlive: true,
      depth: 1
    },
    component: () => import("../views/reservation/reservationList.vue"),
  },
  {
    path: "/reservationDel",
    name: "reservationDel",
    meta: {
      depth: 2
    },
    component: () => import("../views/reservation/reservationDel.vue"),
  }, ,
  {
    path: '/health-told',
    name: 'health-told',
    meta: {
      depth: 3
    },
    component: () => import('../views/reservation/HealthTold.vue'),
  },
  {
    path: '/health-info',
    name: 'health-info',
    meta: {
      depth: 3
    },
    component: () => import('../views/reservation/HealthInfo.vue'),
  }
]

这里我们通过routematedepth属性来定义页面的深度,当然也可以通过路由的嵌套来定义。

然后在App.vuewatch中监听$route的变化,为标签设置动态的name值。这里需要注意的一点是有的页面是由原生页面直接跳转,来源路由的不包含depth属性,所以我们需要设置默认depth值,当页面由原生页面跳转过来时我们将name属性置空,以免和原生跳转效果重叠。

export default {
  data() {
    return {
      transitionName: '',
    }
  },
  watch: {
    $route(to, from) {
      let toDepth = to.meta.depth || 0,
        fromDepth = from.meta.depth || 0
      if (fromDepth === 0) this.transitionName = ''
      else if (toDepth > fromDepth) this.transitionName = 'slide-left'
      else this.transitionName = 'slide-right'
    },
  },
}
</script>

最后,为页面的滑入滑出定义样式:

.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
  will-change: transform;
  transition: all 500ms;
}
.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);
}

最终实现效果:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值