vue 移动端开发优化

146 阅读3分钟

一. 解决用户点击屏幕 300ms 延迟

1.为什么要使用 fastclick

1)移动端的浏览器,默认会在用户点击屏幕300ms 延迟之后,才会触发点击事件。为了检查用户是否在双击、为了响应用户的点击事件,所以有了fastclick 2)移动端浏览器事件执行顺序:touchStart -> touchEnd -> click。由于移动端click事件的滞后性,很有可能上一个页面上同一位置的click事件会在下一个页面的同一位置的元素上执行,导致“点击穿透”。

2.如果移动端不使用click,全部使用touch事件,会怎样?

1)不会有延迟 注意: 如果遇到标签,还要注意把href属性的跳转换成js控制跳转,因为href跳转本质上也是click 2)对于用户来说,有时触发touch事件,只是想滑动屏幕,但是却跳转了页面,这不是他想要的效果。 所以,click事件又是必须的

3. 在vue中使用fastclick

npm install fastclick --安装
main.js 引入使用
import FastClick from 'fastclick'
Fastclick.attach(document.body)

二、优化浏览器前进后退

1)问题描述:导航默认行为类似手机APP的页面导航(A、B、C页面)

    1)A前进到B,再前进到C
    2)C返回到B时,B会从缓存中恢复
    3)B再次前进到C,C会重新生成,不会从缓存中恢复
    4)C前进到A,A会生成,现在路由中包含2个A实例
    
    !!!重要:vue-navigation在url中添加了一个key来区分路由。key的名称默认为VNK,可以修改。
    2)安装使用
    npm install -S vue-navigation
    main.js中引入使用
    import Vue from 'vue'
    import router from './router'
    import Navigation from 'vue-navigation'
    Vue.use(Navigation, {router})
    
    App.vue中:
    <template>
        <navigation>
            <router-view></router-view>
        </navigation>
    </template>
    3)事件:
    this.$navigation.on('forward', (to,from) => {
    });
    this.$navigation.on('back', (to,from) => {
    });
    this.$navigation.on('replace', (to,from) => {
    });
    this.$navigation.off('refresh', (to,from) => {
    });
    this.$navigation.on('reset', (to,from) => {
    });

三、从详情页,返回列表时,回到刚刚浏览的位置

1、问题描述:

点击列表中某条数据,进入详情页。此时返回列表,继续查看列表。这时页面会置顶,用户不得不又重新下拉查看列表,这样做了很多没有必要的操作,不符合用户的预期。

2、解决方法:

1)使用 <keep-alive> 缓存,即不销毁列表页。
    App.vue中:
    <template>
      <div id="app">
        <!-- <router-view/> -->
        <keep-alive>
            <router-view v-if="$route.meta.keepAlive"></router-view>
        </keep-alive>
        <router-view v-if="!$route.meta.keepAlive" />
      </div>
    </template>
    
    router.js中:
    routes: [
    {
      path: '/',
      name: 'List',
      //component: List
      component: () => import('./views/index/list.vue'),
      meta: {
        keepAlive: true // 需要缓存
      }
    },
    {
      path: '/content/:contentId',
      name: 'content',
      component: () => import('./views/index/content.vue'),
      meta: {
        keepAlive: false // 不需要缓存
      }
    },
]
    
2. 使用路由守卫
原理就是在 beforeRouterLeave 的路由钩子记录当前页面滚动位置
    //在页面离开时记录滚动位置,这里的this.scrollTop可以保存在vuex的state或者浏览器本地
beforeRouteLeave (to, from, next) {
    this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
    next()
  },
 
//进入该页面时,用之前保存的滚动位置赋值
beforeRouteEnter (to, from, next) {
    next(vm => {
      document.body.scrollTop = vm.scrollTop
    })
  },
3.使用vue-router方法 scrollBehavior(推荐)
    router.js中:
    const scrollBehavior = function scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    // savedPosition 会在你使用浏览器前进或后退按钮时候生效
    // savedPosition: 会记录滚动条的坐标,点击"后退/前进" 时的记录值(x:?,y:?)
    return savedPosition;
  }else {
      return { x: 0, y: 0 }; // 期望滚动的位置
   }
};
const router = new Router({
  routes,
  scrollBehavior,
});
该方案,直接在路由进行处理,兼容每个页面并且页面加载完后也不会产生1px的滚动位置。
scrollBehavior (to, from, savedPosition)方法接收 tofrom 路由对象。第三个参数 savedPosition当且仅当 popstate 导航(通过浏览器的 前进/后退 按钮触发)时才可用。
    参数:
     to:要进入的目标路由对象,到哪里去
     from:离开的路由对象,从哪儿来
     savedPosition: 会记录滚动条的坐标,点击"后退/前进" 时的记录值(x:?,y:?)
     { x: number, y: number }
     { selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)

四、移动端上,用overflow-y: scroll,滚动效果木讷。

    body {
      -webkit-overflow-scrolling:touch; 
      overflow-scrolling: touch;
    }
    用-webkit-overflow-scrolling: touch属性,让滚动条产生回弹的效果,就像ios原生的滚动条一样流畅。
如果添加动态内容页面不能滚动,让子元素height+1
方法就是在`webkit-overflow-scrolling:touch`属性的下一层子元素上,将 height加1%或1px。从而主动触发scrollbar。
    main-inner {
     min-height: calc(100% + 1px)
    }
    或者:
    main:after {
     min-height: calc(100% + 1px)
    }