- 开始时间:2020-05-31
- 目标主要版本:Vue Router v3 and v4
- 引用 issue:https://github.com/vuejs/vue-router/issues/3008,
- 实现的 PR:N/A
摘要
废弃 selector、x、y 和 offset,改用 el、top、left(和 behavior),与原生 API 保持一致,并且更加灵活。
基本范例
const router = new Router({scrollBehavior(to, from, savedPosition) {// scroll to id `can~contain-special>characters` + 200pxreturn {el: '#can~contain-special>characters'// top relative offsettop: 200// instead of `offset: { y: 200 }`}}})
由 scrollBehavior 返回的其他可能的值:
// scroll smoothly (when supported by the browser) to 400px from top and 20px from left{top: 400,left: 20,behavior: 'smooth'}// scroll smoothly to selector .container{el: '.container'behavior: 'smooth'}// directly pass an Element to `el`{// use the fragment(to.hash) on the url but scroll to a child of it with a class `container`el: document.getElementById(to.hash.slice(1)).querySelector('.container')}
动机
废弃 selector
现有的滚动行为接受一个内部使用 document.querySelector 的 selector 属性。在 vue-router@3 中,我们目前对与 /^#\d/(以数字开头的 ID CSS 选择器)匹配的选择器有一个变通的方法。这是因为这样的选择器是无效的,所以我们检测到它并使用 document.getElementById 代替。然而,当使用像 #1one .container 这样的 CSS 复合选择器时,这就失效了。事实上,还有很多字符需要转义,我们不可能转义所有的字符,这就造成了滚动行为更难使用的情况。除此之外,当 vue-router 因为 document.querySelector 失败而抛出问题时,会让用户感到困惑。
废弃 x、y 和 offset
目前有两种指定偏移量的方法,都使用了与原生函数不同的 x/y 坐标系统:原生浏览器函数允许在 scrollTo 方法中使用一个 [ScrollToOptions](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions)。这个对象包含 top、left 和 behavior 属性。
具体设计
尽管 RFC 中没有任何注视,但 **scrollBehavior** 仍然可以返回上述任何类型的 Promise。我们省略了对返回类型的关注,而不是让它在 scrollBehavior 中等待。
废弃 x 和 y
这与 Element.scrollTo 一致,并使其更自然地传递额外的选项,如 behavior:
{ x: 0, y: 200 }// becomes{ left: 0, top: 200 }// it can accept `behavior`{ left: 0, top: 200, behavior: 'smooth' }
废弃 offset
在指定偏移量时,我们可以直接接受 x、y 和 selector 一起,而不是在选择器旁边接受一个 offset 选项:
{selector: '#getting-started',y: -120,}
在提案的重新命名后,将变为:
{el: '#getting-started',top: -120,}
省略 el 将创建一个绝对偏移,就像我们在 vue-router@3 中提供 x 和/或 y 一样。
更加直观的选择器,感谢 el
一个新的 el 属性的目标是为大多数常见的使用情况提供简单的、“it just works” 的选择器,同时仍然允许高级情况:
to.hash指的是页面上的一个 id,并且直接提供给 el。例如,当to.hash等于#about、#getting-started或#symbols~work时,el: to.hash。el提供了一个更加通用的选择器,不一定来自to.hash。例如,.container > main,任何不以**#**开头的东西都可以。el提供了一个Element,以允许任何高级的使用情况,例如,当to.hash以#开头,但包含一个 CSS 选择器而不是一个 id:document.querySelector(to.hash)。
由于允许原生 Element,这涵盖了所有可能的情况,并使之更容易在事情不成功时向用户提供反馈。
通过警告获得开发者体验
这一变化的另一个重要部分是在开发中,当 vue-router 找不到一个元素或 document.querySelector 抛出一个错误时,会发出警告。我们可以将其分为两种情况:
el 以 # 开头
当 el 以 # 开头时,我们内部使用 document.getElementById(el.slice(1))。如果它没有找到元素,在开发中模式下,我们尝试使用 document.querySelector(${providedEl}) 并解释原因。如果我们什么也没找到,就显示通常的警告:没有找到任何元素。
el 不以 # 开头
在开发者模式下,如果 document.querySelector throw,try catch 会提供一个错误信息,这个信息指向这篇伟大的文章 https://mathiasbynens.be/notes/css-escapes 并且指向 [CSS.escape](https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape)。如果什么都没找到,就显示同样的警告,即没有找到任何元素。
缺点
- 破坏性变化,但可以通过废弃来引入
备选方案
N/A
采纳策略
- 在 v3 中删除
selector、x、y和offset,并提出警告 - 在 v4 中完全删除
没有解决的问题
N/A
注意
本 RFC 不涉及滚动到与窗口不同的元素或一次滚动多个元素的问题。
