详解vue 在移动端体验上的优化解决方案


Posted in Javascript onMay 20, 2019

去年年底自己搭了一个vue在移动端的开发框架,感觉体验不是很好。上个星期又要做移动端的项目了。所以我花了两天时间对之前的那个开发框架做了以下优化

  • 自定义vuex-plugins-loading
  • 路由切换动画 + keep alive 动态管理缓存组件
  • better-scroll与vue的最佳实践(better-scroll的vue化)
  • 自定义指令(vue-finger:包括点击,长按,双击,拖拽移动,多点触控,滑动,旋转,缩放手势)
  • 移动端适配方案
  • 如何分情况处理页面置顶
  • 路由懒加载

自定义 vuex-plugins-loading

如果每个页面在数据加载完成前,展示loading。你首先想到的是每个页面设置状态,show和hide状态。但是这样冗余代码太多了,而且自己写的都烦。我之前的react的项目中用到了dva,其中有dva-loading库,之前就有研究过,所以我就用他的思想,自己写一个vuex-loading。

实现思路:vuex中注册一个管理loading的module,通过绑定异步的action,将每个action的loading存在vuex中,这样我在每个页面只需要在vuex的store中拿相对应的action loading就能达到此目的

## 核心代码
  store.subscribeAction({
   before: action => {
    if (shouldEffect(action, includes, excludes)) {
     store.commit({ type: namespace + '/SHOW', payload: action.type })
    }
   },
   after: action => {
    if (shouldEffect(action, includes, excludes)) {
     store.commit({ type: namespace + '/HIDE', payload: action.type })
    }
   }
  })
 }
}

使用之前大家可以先了解一下subscribeAction

想安装此插件,请点击这里,记得给个star哟

注意: 使用上述代码,vuex必需为3.1.0版本。因为subscribeAction在3.1.0才新增的

路由切换动画 + keep alive 动态管理缓存组件

之前采用的是全局设置路由切换动画,但是体验效果不是很好,特别是返回列表页,页面会引起回弹,页面切换时会有暂时的空白。

未改造前的,也是参考别人的做法

## app.vue
 <transition :name="transitionName"> 
  <keep-alive :include="data">
    <router-view></router-view>
  </keep-alive>
 </transition>
 
 computed: {
  // 数据存放在vuex里面
  ...mapState({
   data: state => {
    return state.global.data
   }
  })
 },
 methods: {
  // 设置Keep_alive路由
  setKeep_alive (to) {
   if (to.meta.keepAlive) {
    this.$store.dispatch({
     type: 'global/setData',
     payload: to.name
    })
   }
  }
 },
 watch: {
  '$route' (to, from) {
   // 此时从from页面跳转到to页面
   this.setKeep_alive(to)
   const routeDeep = ['/', '/list', '/detail', '/reservation', '/addCars']
   const toDepth = routeDeep.indexOf(to.path)
   const fromDepth = routeDeep.indexOf(from.path)
   if (!from.name) {
    this.transitionName = 'fold'
    return
   }
   this.transitionName = toDepth > fromDepth ? 'fold-left' : 'fold-right'
  }
 },
## router.js
scrollBehavior (to, from, savedPosition) {
  // keep-alive 返回缓存页面后记录浏览位置
  if (savedPosition && to.meta.keepAlive) {
   return savedPosition
  }
  // 异步滚动操作
  return new Promise((resolve) => {
   setTimeout(() => {
    resolve({ x: 0, y: 1 })
   }, 0)
  })
 },

两个问题

列表页滑动到一定位置后跳转到详情页,返回列表页页面回弹

原因:原生滚动条的位置是不变的,使用scrollBehavior,根据上述代码可知滚动条会有一个闪烁的过程先置顶,然后滚动到上次保留的位置。

页面切换时会有暂时的空白,过渡不正常。

改造后

## app.vue
<keep-alive :include="data">
 <router-view></router-view>
</keep-alive>
computed: {
  // 数据存放在vuex里面
  ...mapState({
   data: state => {
    return state.global.data
   }
  })
 },
 methods: {
  // 设置Keep_alive路由
  setKeep_alive (to) {
   if (to.meta.keepAlive) {
    this.$store.dispatch({
     type: 'global/setData',
     payload: to.name
    })
   }
  }
 },
 watch: {
  '$route' (to, from) {
   // 此时从from页面跳转到to页面
   this.setKeep_alive(to)
  }
 },

list.vue

<Scroll
 ref="scroll"
 class="scroll-home"
 :scrollbar="scrollbar"
 :probeType="3"
 :pullDownRefresh="pullDownRefresh"
 :pullUpLoad="true"
 @pullingDown="onRefresh"
 @scroll="scroll"
 @pullingUp="onLoad"
>
 <div class="contantView">
 </div>
</Scroll>

1.采用better-scroll后,第一个问题可以直接解决。而且不用设置scrollBehavior,不懂可以去看better-scroll

2.给页面CSS添加设置“position:absolute;”,此时页面脱离文档流,不占空间,这样就不会把下一页挤下去,完成平滑过渡。使用better-scroll给页面CSS添加设置“position:fixed;”。

如果页面布局里面有用到flex布局,一定要给flex组件加一个position为absolute或者fixed的div。

上述代码中已有keep alive 动态管理缓存路由的思路。

better-scroll与vue的最佳实践

之前在一篇文章上看到BetterScroll可能是目前最好用的移动端滚动插件,所以这次就想试试,滴滴开源的cube-ui组件库里面大多数用到的滑动组件都是基于better-scroll,体验了一下感觉还挺好。为什么没有用cube了?因为个人感觉主题颜色有点丑。所以自己就打算基于better-scroll封装一个vue版本的scroll组件。不说那么多了,立马上图:

详解vue 在移动端体验上的优化解决方案

想用better-scroll还有另外一个原因,我想自定义上下拉的动画。

想看demo及源码请点击这里。记得给个star哟

自定义指令 vue-finger

包括点击,长按,双击,拖拽移动,多点触控,滑动,旋转,缩放手势

这一块我这边是基于别人的demo改造的,在这些指令里面你可以做很多在移动端手势方面想做的事情。后续我会继续迭代这些指令,制定出体验接近原生的组件,大家要关注我的github哟

移动端适配方案

## rem.js
const baseSize = 32
// 设置 rem 函数
function setRem () {
 // 当前页面宽度相对于 750 宽的缩放比例,可根据自己需要修改。
 const scale = document.documentElement.clientWidth / 750
 // 设置页面根节点字体大小
 document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px'
}
// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function () {
 setRem()
}
## main.js
import './rem'

还有最后还有一步。对于经常写样式的同学,px转rem是不是感觉很烦。 我这边处理的方式是,在项目根目录新建一个postcss.config.js文件。这样你只需按照设计稿的样式,正常写px就好。运行项目时会自动帮你转成rem。

module.exports = {
 plugins: {
  'autoprefixer': {
   browsers: ['Android >= 4.0', 'iOS >= 7']
  },
  'postcss-pxtorem': {
   rootValue: 16,
   propList: ['*']
  }
 }
}

如何分情况处理页面置顶

上文有讲到vue-router里面scrollBehavior这个方法。

## router.js
scrollBehavior (to, from, savedPosition) {
  // keep-alive 返回缓存页面后记录浏览位置
  if (savedPosition && to.meta.keepAlive) {
   return savedPosition
  }
  // 异步滚动操作
  return new Promise((resolve) => {
   setTimeout(() => {
    resolve({ x: 0, y: 1 })
   }, 0)
  })
 },

但是感觉添加页面转场动画后。页面会有回弹。所以我就放弃它了。不添加动画的可以考虑。

我这边用到了better-scroll后就不用担心这个问题。看完better-scroll文档介绍,你就会发现better-scroll就是为移动端运用而生的。

路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。 这是路由懒加载就很重要了。看过官方文档大家应该都会用了,这里我就不介绍了。

// 路由懒加载
const _import_ = file => () => import('./views/' + file + '.vue')

routes: [
  {
   path: '/',
   name: 'home',
   component: _import_('Home/Home'),
   meta: {
    title: '首页',
    keepAlive: true
   }
  },
]

终于写完了,以上这些就是我在移动端体验优化的实战。希望能帮到大家。如果往后有什么好的优化方案我会继续更新。谢谢大家的观看。觉得好的点个赞

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
Sep 27 Javascript
简单实用的全选反选按钮例子
Oct 18 Javascript
js中string转int把String类型转化成int类型
Aug 13 Javascript
javascritp添加url参数将参数加入到url中
Sep 25 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
Oct 22 Javascript
JavaScript DOM 学习总结(五)
Nov 24 Javascript
jQuery实现图像旋转动画效果
May 29 Javascript
js简单获取表单中单选按钮值的方法
Aug 23 Javascript
JavaScript实现读取与输出XML文件数据的方法示例
Jun 05 Javascript
Vue路由模块化配置的完整步骤
Aug 14 Javascript
layui的select联动实现代码
Sep 28 Javascript
浅谈vue项目,访问路径#号的问题
Aug 14 Javascript
vue-i18n结合Element-ui的配置方法
May 20 #Javascript
JS实现选项卡效果的代码实例
May 20 #Javascript
微信打开网址添加在浏览器中打开提示的办法
May 20 #Javascript
浅谈Vuex注入Vue生命周期的过程
May 20 #Javascript
微信小程序图表插件wx-charts用法实例详解
May 20 #Javascript
Nuxt项目支持eslint+pritter+typescript的实现
May 20 #Javascript
vue3.0 搭建项目总结(详细步骤)
May 20 #Javascript
You might like
php用header函数实现301跳转代码实例
2013/11/25 PHP
Laravel5.1 框架Middleware中间件基本用法实例分析
2020/01/04 PHP
些很实用且必用的小脚本代码
2006/06/26 Javascript
Javascript的IE和Firefox兼容性汇编
2006/07/01 Javascript
用正则xmlHttp实现的偷(转)
2007/01/22 Javascript
超级简单的图片防盗(HTML),好用
2007/04/08 Javascript
javascript中创建对象的三种常用方法
2010/12/30 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
Javascript中arguments对象的详解与使用方法
2016/10/04 Javascript
vue绑定class与行间样式style详解
2017/08/16 Javascript
angular4模块中给标签添加背景图的实现方法
2017/09/15 Javascript
微信小程序实现红包功能(后端PHP实现逻辑)
2018/07/11 Javascript
js JSON.stringify()基础详解
2019/06/19 Javascript
layui多图上传实现删除功能的例子
2019/09/23 Javascript
python基础教程之匿名函数lambda
2017/01/17 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
Python pandas.DataFrame调整列顺序及修改index名的方法
2019/06/21 Python
python之pexpect实现自动交互的例子
2019/07/25 Python
pytorch获取模型某一层参数名及参数值方式
2019/12/30 Python
linux 下python多线程递归复制文件夹及文件夹中的文件
2020/01/02 Python
python TCP包注入方式
2020/05/05 Python
浅谈keras中的目标函数和优化函数MSE用法
2020/06/10 Python
python中count函数知识点浅析
2020/12/17 Python
VSCode 自定义html5模板的实现
2019/12/05 HTML / CSS
Jimmy Choo美国官网:周仰杰鞋子品牌
2018/06/08 全球购物
英国领先的电动可调床制造商:Laybrook
2019/12/26 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
将一个数的从第5位开始的7个数取出,其余位置0
2016/05/26 面试题
使用Vue.js和MJML创建响应式电子邮件
2021/03/23 Vue.js
幼儿园教师个人反思
2014/01/30 职场文书
护士2014年终工作总结
2014/11/11 职场文书
房屋认购协议书
2015/01/29 职场文书
服务行业标语口号
2015/12/26 职场文书
个人工作失误的保证书怎么写?
2019/06/21 职场文书
2019年警察入党转正申请书最新范文
2019/09/03 职场文书