关于一个交互细节的讨论

858 阅读4分钟

我们先看一个实际例子:

image

点击菜品详情,按返回直接退出了店铺,这个例子还不是明显,在有很多小店铺的点单系统,连购物车都是一个纯组件,我进入购物车,按返回直接就退出页面了,更恶心有的没做记录,再次进去就空了

哪怕是各大厂的移动端应用也经常会看到这种尴尬的交互,这类的弹窗组件,在pc端,因为窗口足够大,通常也会有在右上角有关闭❌按钮,用户也习惯与这种操作,

但在vue移动端项目中,这类型,例如选择框/搜索框,比较主流的交互方式是,点击遮罩或者下方❌关闭,这种交互还算ok

但是有一些极端的情况下,我们可能需要整个弹窗是全屏幕,例如带搜索的选择组件,例如国籍/地址等

纯组件

最开始,使用纯组件,v-show展示

image

这种情况下,在用户的意识里,已经切换了页面 所以在安卓用户想返回的话,会下意识点物理返回 这时候就悲剧了,直接回到了上一页,而不是关掉当前激活的组件,测试直接给我提了一堆bug

子路由组件

基于这一点,最开始是用子路由思路做,这几乎完美解决保留完整的页面状态并跳转出一个新路由

image

只是依然存在一个严重副作用,所有子路由公用一个router-view,如果通过这个标签传参的话,子路由多了的情况下,难免会存在重名问题,当然是你自己设计的组件,通过前缀来解决也并非不可

并且随着越来越多的页面使用,就发现写法臃肿,这种状况持续大半年,随着业务量增加,需要嵌套子路由越来越多,大量重复的代码也非常难看。

插件式组件

终于开始着手做一些改动了

这过程考虑过的思路:

  1. 跟产品各种撒泼赖皮,把全屏的组件都设计成带遮罩的半屏组件,不给客户跳转了新页面的错觉,但始终是有些组件需要必须全屏的,不然可操作的区域是在太小
  2. 发现当输入框聚焦时,键盘弹起,按一次返回可以收起键盘;一顿操作之后,只有键盘弹起的情况,才可以能抵挡一次物理键返回,阻止键盘弹起本身也很难实现,无果。。。

最终确定的方案是插件式调用结路由哈希创建一条记录,主要代码如下:

let $vm
let $watcher

export function createDOM () {
  if (typeof document === 'undefined') {
    return
  }
  const MyComponent = Vue.extend(component)
  const $vm = new MyComponent({
    el: document.createElement('div')
  })
  document.body.appendChild($vm.$el)
  return $vm
}

export function install () {
  if (!$vm) {
    $vm = createDOM()
    Vue.prototype.$plugin = obj
  }
}

export function show (options) {

  const { cb } = options
  if (cb) {
    $vm.cb = cb
  }
  listening(hide)
  const { path, query, params } = router.currentRoute
  router.push({
    path,
    query,
    params,
    hash: 'pluginHash'
  })

  $watcher && $watcher()
  $watcher = $vm.$watch('targetValue', (val) => {
    if (val === false) {
      hide()
      $watcher && $watcher()
    }
  })
  $vm.targetValue = true
}

export function hide () {
  $vm.targetValue = false
  $vm.$nextTick(() => {
    $watcher && $watcher()
    $watcher = null
    if (window.location.hash.indexOf('pluginHash') !== -1) {
      router.go(-1)
    }
  })
}

image

这是还有一点副作用的,和子路由一样会在history最前端创建了一条记录,尤其是微信7.0后,把前进后退按钮搬到下面了,如果用户点前进的话还是有点尴尬的,history并没有给我们提供类似pop的方法,但至少调用起来很方便,也不会有太多莫名的子路由嵌套。 大家有什么好的套路,也可以在评论区一起交流,

但就目前来看,越来越多的安卓机加入全面屏的阵营,取消了物理返回健,当全面屏成为主流,对于前端来说倒也省去很多这类的交互问题

本文git地址

后记

最近因为项目迁移升级,再加上搬家之类的私事,停下了小白路的更新,不过没关系,预计两周后会恢复正常更新,顺便预告下,小白路的第一个小游戏是扫雷已经完成了,还在优化中,下一次大可能与算法或单元测试相关,希望后面的能给大家带来更多干货