taro-rfcs icon indicating copy to clipboard operation
taro-rfcs copied to clipboard

实现 History API

Open cncolder opened this issue 5 years ago • 3 comments

完整提案请看: https://github.com/cncolder/taro-rfcs/blob/history-api/rfcs/0000-history-api.md

cncolder avatar May 15 '20 11:05 cncolder

Taro 是基于微信小程序规范做的一个解决方案,路由机制也是按微信小程序规范制定的,而 @tarojs/runtime 是为了更好地实现这个规范的中间层。这句话其实包括整个 Taro Next 核心架构的关键点:规范是关键,运行时是手段,而不是目的。@tarojs/runtime 选择使用 DOM 层作为中间层也是实现这个规范的一种手段,不应该把实现 DOM/BOM 作为目的。

如果能帮助开发者提升开发效率或开发体验的手段当然是好的,但前提是不违反规范。按微信的路由规范其实是和 history 的 API 是有部分冲突的,例如 navigateTo 不会卸载上一个页面组件,而 redirectTo 又会卸载上一个页面组件。如果多了一个选项,例如可以选择 react-routervue-router,开发者反而会陷入迷惑,不知道什么时候自己的页面会卸载,什么时候会隐藏。

当然实现自己的路由系统也给了开发者更多的选择和控制权,同时也会增加额外的复杂度(包括对开发者使用的复杂度和对 Taro 实现的复杂度)。更重要的是,实现自己的路由系统也会和原生的路由系统冲突。不仅仅是在小程序的原生路由系统冲突,也会和 Taro 在 H5/RN 基于小程序规范的路由系统冲突。

yuche avatar May 19 '20 07:05 yuche

提案中为了实现 history api, 难度确实有些大, 当初是想实现 history 中的效果.

经过尝试, 给 Current.router 属性定义 setter, 根据 getCurrentPages() 的前后差异推断等方式, 目前实现了以下效果:

import appConfig from '@/app.config'

const history = createTaroHistory({ appConfig })
  • [x] history.push
  • [x] history.replace
  • [x] history.goBack
  • [x] history.go(/* n < 0 /*)
  • [x] history.length
  • [x] history.location
  • [x] history.action
  • [x] history.listen

其中 history.listen 在点击"返回按钮"和使用 <Navigator /> 组件时都能触发.

navigateBack 和 switchTab 在极端情况下分不清.

未实现(理论上可行):

  • [ ] history.go(/* n > 0 /*)
  • [ ] history.goForward()

cncolder avatar May 20 '20 06:05 cncolder

绕过 History API, 改为直接仿照 history 模块实现类似效果. https://github.com/tarojsx/history 因为用到了 window.__taroAppConfig, 需要 taro 3.0.0-rc.1 以上版本.

如果 Current.router 在赋值时可以触发一个事件, 就可以避免对其进行 monkey patch.

cncolder avatar May 27 '20 18:05 cncolder