移动端底层事件(如左滑返回事件)在同一个路由下不同页面需要不同的处理要怎样才能做到统一处理?

目录

一、问题

二、解决方法

三、总结


tiips:如嫌繁琐,直接移步总结即可!

一、问题

1.测试提了个bug:进入了一个模块A里面的子页面 a1,左滑后按照用户预期应该是返回到模块A,结果回到了app首页

二、解决方法

1.一开始:啊,有毒呀,一个模块里面只用了一个路由,我也不能全局控制每个页面到底要返回到哪个页面呀。。。。。。

2.天哪,太难了,难道要在接收到 底层事件时,设置一个变量,根据变量判断到底返回到哪里,然后还要把标志位复原?这个工作量不是一般的大呀,还要每个页面写逻辑差不多的代码。

3.没错,屈服了,准备按照2来执行了。执行过程中发现太难了,放弃。

4.看到移动端底层给的事件是全局注册的,为什么我不能注册一个全局返回函数呢?不同的页面本来就有返回按钮,事件也写好了。只要我能够在监听到移动端底层事件时,统一调用这个函数就可以了呀!

5.竟然可以!!!

6.整体思路

   1)路由首页:对于一个模块的入口页面,左滑返回上一个路由 router.back()

    2)同一个路由下的子页面注册函数backPreviousPage,函数的具体内容对应该子页面下面的返回函数,左滑执行backPreviousPage函数,然后销毁backPreviousPage函数

    3)首页:对于app首页,左滑退出app

7.代码如下:

1)简略代码:

//左滑事件处理
window['eventFromMobile'] = eventFromMobile;
const eventFromMobile=(eventArgs)=>{
  let current = router.history.current;
  let { eventType } = JSON.parse(eventArgs)
  switch(eventType){
    //左滑
    case 'KEYCODE_BACK':
      //同一个路由对应的中间页左滑
      if(typeof(window['backPreviousPage'])==='function'){
        window['backPreviousPage']()
        window['backPreviousPage']=null;
      }
      //首页
      else if(current.meta.homePage){
        Modal({
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          message: '确定退出应用吗?'
        })
          .then(() => {
            //退出
          })
          .catch(() => { });
      }
      //路由首页
      else{
        router.back()
      }
      break;
  }
}

//模块A下面的子页面注册 backPeviousPage事件
    onMounted(() => {
      getData([0, 2], false);
      
      //很重要!!!  一行代码就可以了
      window['backPreviousPage'] = goBack
    });
    //返回
    const goBack = () => {
      emit("closeComponent");
    };

2)完整代码

a.左滑主要处理逻辑

//左滑主要处理逻辑
import VueRouter from 'vue-router';
const routes = [
  {
    path: '/',
    redirect: '/task'
  },
  {
    // 登录页
    path: '/login',
    name: 'login',
    component: login,
    meta: { keepAlive: false, title: '登录', filter: true, footer: 'login' }
  },
  {
    // 登录页
    path: '/layout',
    name: 'layout',
    redirect: '/task',
    component: layout,
    children: [
      {
        path: '/task',
        name: 'task',
        meta: { title: '工作台', footer: 'task', keepAlive: true },
        component: (r) => require.ensure([], () => r(require('@/views/task/homePage/index.vue')), 'task')
      },
      {
        path: '/message',
        name: 'message',
        meta: { title: '消息', footer: 'message', keepAlive: true },
        component: (r) => require.ensure([], () => r(require('@/views/message')), 'message')
      },
      //模块A
      {
        path: '/deviceMeasure',
        name: 'deviceMeasure',
        meta: { title: '模块A', keepAlive: true },
        component: (r) =>
          require.ensure([], () => r(require('@/views/task/qualityControl/taskPage'), 'deviceMeasure'))
      },
      //模块B
      {
        path: '/deviceQuality',
        name: 'deviceQuality',
        meta: { title: '模块B', keepAlive: true },
        component: (r) =>
          require.ensure([], () => r(require('@/views/task/qualityControl/deviceQuality/index.vue'), 'deviceQuality'))
      },
    ]
  }
];
const router = new VueRouter({
  mode: 'hash',
  base: process.env.NODE_ENV === 'production' ? '/yzl/mems' : '/mems',
  routes: routes
});

//左滑事件处理
window['eventFromMobile'] = eventFromMobile;
const eventFromMobile=(eventArgs)=>{
  let current = router.history.current;
  let { eventType } = JSON.parse(eventArgs)
  switch(eventType){
    //左滑
    case 'KEYCODE_BACK':
      //同一个路由对应的中间页左滑
      if(typeof(window['backPreviousPage'])==='function'){
        window['backPreviousPage']()
        window['backPreviousPage']=null;
      }
      //首页
      else if(current.meta.homePage){
        Modal({
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          message: '确定退出应用吗?'
        })
          .then(() => {
            //退出
          })
          .catch(() => { });
      }
      //路由首页
      else{
        router.back()
      }
      break;
  }
}

b.同一个路由下的子页面

<template>
  <!-- 任务详情 -->
  <div :class="['task-detail-wrap', { 'mask-area': isShowSecondLevel }]">
    <div class="top-area">
      <div class="head-area">
        <ComHeader back :title="taskInfo.name" @goBack="goBack"> </ComHeader>
        <div class="chart-area">
        </div>
      </div>
    </div>
    <div class="bottom-area">
    </div>
  </div>
</template>
<script>
import {
  defineComponent,
  getCurrentInstance,
  onMounted,
  reactive,
  ref,
} from "vue";
import CircleChart from "@/components/Chart/circleChart.vue";
import RadioFilter from "@/components/Filter/radioFilter.vue";
import ScrollList from "@/components/scrollList/index.vue";
import Card from "@/components/Card/index.vue";
import PlaceImg from "@/components/placeImg/index.vue";

export default defineComponent({
  components: {
    CircleChart,
    RadioFilter,
    ScrollList,
    Card,
    PlaceImg,
  },
  props: {
    taskInfo: {
      type: Object,
      default: () => {
        return {};
      },
    },
    getStatisticAPI: {
      type: Object,
      default: () => {
        return {};
      },
    },
    getDeviceAPI: {
      type: Object,
      default: () => {
        return {};
      },
    },

    config: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  setup(props, { emit, slots, attrs }) {
    const { proxy } = getCurrentInstance();
    onMounted(() => {
      getData();

      //加这一行就可以!!!
      window['backPreviousPage'] = goBack
    });
    //返回
    const goBack = () => {
      emit("closeComponent");
    };


    //3.获取数据
    const getData = () => {
    };


    return {
      goBack,
    };
  },
});
</script>

3)实现效果如下:左滑和点击页面左上角返回的页面完全一致。

三、总结

1.对移动端底层的事件统一处理路由相同时不同页面需要不同处理时在对应的页面注册全局函数,统一调用;一行代码解决了之前每个页面要写很多逻辑的复杂想法。

2.对于其他类似的所有页面的整体逻辑一致,但是具体的处理方式有细微差别的情况,也可以考虑注册一个全局函数,统一调用执行并且在适当的时候销毁函数

3.可能简单的方法千千万万,但是没想到的时候就是 焦头烂额,一筹莫展。

4.希望这样的灵感多一点,问题解决了,好开心 ^_^

/*

希望对你有帮助!

如有错误,欢迎指正,非常感谢!

*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值