路由系统 #10
Replies: 8 comments 11 replies
-
是否支持多个路由匹配同一元素,比如
|
Beta Was this translation helpful? Give feedback.
-
有两个疑问:
|
Beta Was this translation helpful? Give feedback.
-
<examples-news-detail route-path="/news/:id" route-params="{"id":"1024"}"></examples-news-detail> const element = document.querySelector('examples-news-detail');
const id = element.route.params.id; // "1024" 现在路由参数是需要挂在目标元素吗?是否可以提供如: window.WebRouter.route.params
window.WebRouter.route.query 用于获取当前路由参数,这样可以把参数从目标元素移除,还是因为考虑到 SSR 才需要在目标元素附加参数? |
Beta Was this translation helpful? Give feedback.
-
有个想法,在目标元素引用路由参数,和 SVG 的 <svg>
<!-- symbol definition NEVER draw -->
<symbol id="sym01" viewBox="0 0 150 110">
<circle cx="50" cy="50" r="40" stroke-width="8" stroke="red" fill="red"/>
<circle cx="90" cy="60" r="40" stroke-width="8" stroke="green" fill="white"/>
</symbol>
<!-- actual drawing by "use" element -->
<use xlink:href="#sym01"
x="0" y="0" width="100" height="50"/>
<use xlink:href="#sym01"
x="0" y="50" width="75" height="38"/>
<use xlink:href="#sym01"
x="0" y="100" width="50" height="25"/>
</svg> web-router 中: <web-router id="web-router" params="{"id":"1024"}>
<web-route path="/" element="examples-home"></web-route>
<web-route path="/news" element="examples-news"></web-route>
<web-route path="/news/:id" element="examples-news-detail"></web-route>
<web-route path="/about" element="examples-about"></web-route>
<examples-news id="#web-router.params.id" ></examples-news>
</web-router> 其实和 vue 组件引用路由参数形式有点像 <template>
<component :id="$route.params.id"></component>
</template> |
Beta Was this translation helpful? Give feedback.
-
似乎无法定义激活路由的渲染位置,类似 react-router 的 outlet |
Beta Was this translation helpful? Give feedback.
-
更新:
原因:
|
Beta Was this translation helpful? Give feedback.
-
更新:删除 |
Beta Was this translation helpful? Give feedback.
-
更新:使用 |
Beta Was this translation helpful? Give feedback.
-
描述
Web Router 是一个由 Growing Web 提出的路由技术标准,它定义了路由配置与接口的标准实现。
Web Router 路由系统在 Growing Web 架构中的位置:
动机
技术栈中立
如今,越来越多的 Web 框架使用了基于浏览器的路由技术来提升用户体验以及组件解耦,通常这样的路由的实现会与具体的 Web 框架绑在一起,这样的好处是能够提供高效的开发体验,但是应用规模变得庞大后,这样的设计将会增加技术升级的难度,也让不同技术栈与版本的应用集成变得困难。技术栈中立的路由系统将只关注最本质的东西,这样应用在需要的时候可以从局部开始升级技术栈,而不影响其他模块。
可拆卸
一个“微应用”应当工作在路由驱动的架构中,也能够在页面中一个小区块中工作,因此路由系统在“微前端”架构中应当是可选的,它允许从大系统中拆卸为独立的部分。
可组合
路由系统是一个基础的服务,它应当充当好桥梁的角色,将更多的服务交给其他工具完成,例如元素加载器、应用容器、其他前端框架的路由系统等。
基本示例
路由
Web Router 使用 HTML 标签来配置路由。
上述例子中,
<script type="routemap">
为路由的配置,<web-router>
元素为路由的出口。以如下配置举例:
当访问
/news
的时候,将会创建匹配的元素。导航
获取 URL 参数
当路由匹配后,创建的组件将会包含
routeparam-*
属性,其记录了路由的参数信息。后代路由
当父路由路径末尾包含
/*
的时候能够匹配所有的后代路由。上述例子中,无论 URL 是
/news
、/news/1024
、/news/1024/new
都会被匹配到。404 路由
使用
*
可以匹配任何路径,因此它能够充当 404 的路由。按需加载元素
Web Router 的核心功能只包括路由配置以及渲染匹配的元素,加载元素不是它的职责,这些功能可以交给诸如“自定义元素加载器”来实现。
例如与 Web Component 的模块化加载器—— Web Component Modules 一起工作:
访问
/news
时将创建:Web Component Modules 会根据
is="web-component-module"
标记与import
属性加载自定义元素的class
并且注册自定义元素。与前端框架配合
和上述按需加载元素的问题类似,Web Router 可以借助第三方的“应用容器”与各种前端框架构建的应用一起工作,而不必须使用 Web Component 编写应用。
例如与“应用容器”—— Web Widget 一起工作:
访问
/news
时将创建:Web Widget 将会根据
import
属性加载应用的入口文件,然后调用应用生命周期。详细设计
匹配语法
Web Router 的匹配语法不区分大小写。
标准
这条路由只能是完全匹配的。
变量
该路由包含变量
type
,它可以被路由创建的元素获取到。后代
该路由匹配自身与后代路径。例如
/stocks
、/stocks/
、/stocks/3434/edit
。任意
该路由匹配任意的路径,用来做 404 等后备。
匹配优先级
优先级从上至下。
路由配置
路由使用 HTML 标签来声明,这样做的目的是为了能够被序列化,并且能够清晰的知道将在哪里渲染激活后的元素。路由是静态声明的,这也意味着通过 JavaScript 动态创建的将不会生效。
path
路径element
元素名attributes
属性渲染
<web-router>
元素充当路由渲染容器。当路由规则激活后,将会创建元素到<web-router>
元素末尾,而非激活的元素将会被删除或隐藏。路由创建的元素会添加
routepattern
属性,它等价于<web-route>
的path
。如果路由中包含变量,那么创建的元素中会添加
routeparam-*
属性以记录参数值。异步元素
默认情况下匹配的路由以同步更新元素,但是当元素具备诸如“应用容器”特征的时候,Web Router 会将它们当作异步元素处理,以改善用户体验。
包含所有下述方法将被当作“应用容器”元素:
load()
bootstrap()
mount()
unload()
针对“应用容器”元素的具体处理逻辑取决于 Web Router 具体的路由系统实现(也可以完全忽略异步元素)。
base
(需要补充说明
<base>
元素对路由的影响)导航
导航标签
当
<a>
标签添加is="web-link"
属性后,它将阻止默认的浏览器跳转行为,而使用 Web Router 的路由系统进行导航,它可以避免整个页面进行刷新。使用
<a>
标签的原因:不使用诸如
<web-link>
等自定义标签包装<a>
标签的原因:<web-link>
的导航功能必须由 JavaScript 定义才能使用(毕竟 Web Router 不是浏览器标准),这会导致应用从 Web Router 中拆卸后就无法工作了 。is
属性也是 Web Components 的一部分,它容易实现。属性
href
: 目标 URL。state
: 附加在路由上的状态对象。例如<a is="web-link" state="{"id":"1024"}">
。replace
: 是否用一个新位置替换历史堆栈中的当前位置。active
: 导航高亮时会自动增加此属性。end
: 它将确保当其后代路径匹配时,<a>
不会标记为active
。例如,要呈现仅在网站根目录而不是任何其他 URL 的链接,你可以使用<a is="web-link" href="/" end>Home</a>
。导航接口
WebRouter.navigate(to, { replace, state })
参数
to
:string
新地址。replace
:boolean
是否用一个新位置替换历史堆栈中的当前位置。state
:object
要与新位置关联的数据。最佳实践
Web Router API 是一个底层 API,它被设计为给其他工具使用,因此最好不要直接让应用调用 Web Router API。好的做法是封装成工具函数或者一个自定义元素后再使用,这样可以避免应用与 Web Router 环境产生强耦合。
事件
如下行为将会触发 Web Router 导航流程:
<a is="web-link">
元素WebRouter.navigate()
接口导航变更的时候,会在
window
上触发一系列的导航事件。上述所有的事件类型都接收
NavigationChangeEvent
Event 对象。它的属性:newPathname
: 即将前往的新地址oldPathname
: 旧地址state
: 状态对象navigationwillchange
导航即将要开始。此事件可以被取消,取消后将阻止默认的导航行为。
navigationstart
导航开始。
navigationend
导航完成。
navigationerror
导航错误。例如元素挂载时出错。
采用策略
Growing Web
组织的仓库中开发,包命名为:@growing-web/web-router
。兼容性
与 Vue2.x 兼容性
is
属性是 Web Component 对原生标签的扩展的标记,但是 Vue 2.x 故意将is="xxx"
属性当作自己的属性来处理,这会导致导航标签无法工作(Vue 3.x 号称避免了与 Web Component 冲突问题 )。Vue 2.x 将会生成:
在 Vue 2.x 中使用
v-html
来输出<a is="web-link">
标签可以避免这样的问题发生。与 Safari 兼容性
Safari 似乎不支持扩展原生标签,这会导致
<a is="web-link">
降级到原生的<a>
标签的浏览器默认功能,即它会重载入整个页面。详情:WebKit bug 182671。未来的可能性
Web Router 的设计参考了流行的 Web 前端框架路由系统,当前它只定义了最核心的部分,保留了发展的可能,包括如下特性:
示例:嵌套路由
当访问
/news
,会生成如下结构的 DOM:示例:Layout
上述例子中,
<examples-news>
的渲染位置可以由<app-layout>
元素的<slot>
决定:参考
Beta Was this translation helpful? Give feedback.
All reactions