"use strict";(self.webpackChunkfes_js=self.webpackChunkfes_js||[]).push([[626],{6254:(n,s,a)=>{a.r(s),a.d(s,{data:()=>p});const p={key:"v-6320961c",path:"/guide/route.html",title:"路由",lang:"zh-CN",frontmatter:{},excerpt:"",headers:[{level:2,title:"路由配置",slug:"路由配置",children:[{level:3,title:"routes",slug:"routes",children:[]},{level:3,title:"mode",slug:"mode",children:[]}]},{level:2,title:"约定式路由",slug:"约定式路由",children:[{level:3,title:"约定规范",slug:"约定规范",children:[]},{level:3,title:"动态路由",slug:"动态路由",children:[]},{level:3,title:"嵌套路由",slug:"嵌套路由",children:[]},{level:3,title:"模糊匹配",slug:"模糊匹配",children:[]},{level:3,title:"扩展路由元信息",slug:"扩展路由元信息",children:[]},{level:3,title:"智能路由",slug:"智能路由",children:[]}]},{level:2,title:"路由跳转",slug:"路由跳转",children:[{level:3,title:"声明式",slug:"声明式",children:[]},{level:3,title:"命令式",slug:"命令式",children:[]}]}],filePathRelative:"guide/route.md",git:{updatedTime:1653450562e3,contributors:[{name:"wanchun",email:"445436867@qq.com",commits:1}]}}},7570:(n,s,a)=>{a.r(s),a.d(s,{default:()=>an});var p=a(6252);const t=(0,p._)("h1",{id:"路由",tabindex:"-1"},[(0,p._)("a",{class:"header-anchor",href:"#路由","aria-hidden":"true"},"#"),(0,p.Uk)(" 路由")],-1),e=(0,p.Uk)("像 Vue 、React 这类框架是用组件化搭建页面,路由解决的是路径到组件的匹配问题。Fes.js 基于 "),o=(0,p._)("code",null,"Vue Router",-1),r=(0,p.Uk)(" 实现的路由,想了解更多的同学可以看看"),l={href:"https://next.router.vuejs.org/",target:"_blank",rel:"noopener noreferrer"},c=(0,p.Uk)("官方文档"),u=(0,p.Uk)("。"),i=(0,p.uE)('
在配置文件 .fes.js
中通过 router
进行配置。
export default {\n router: {\n routes: [],\n mode: 'hash'\n }\n}\n
默认是hash
模式。
约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
比如以下文件结构:
pages\n├── index.vue # 根路由页面 路径为 /\n├── *.vue # 模糊匹配 路径为 *\n├── a.vue # 路径 /a\n├── b # 文件夹b\n│ ├── index.vue # 路径 /b\n│ ├── @id.vue # 动态路由 /b/:id\n│ ├── c.vue # 路径 /b/c\n│ └── layout.vue # /b 路径下所有页面公共的布局组件\n└── layout.vue # 根路由下所有页面共用的布局组件\n
编译后会得到以下路由配置:
[\n {\n "path": "/",\n "component": require('@/pages/layout').default,\n "count": 5,\n "children": [\n {\n "path": "/a",\n "component": require('@/pages/a').default,\n "name": "a",\n "meta": {},\n "count": 7\n },\n {\n "path": "/b",\n "component": require('@/pages/b/layout').default,\n "count": 7,\n "children": [\n {\n "path": "/b/c",\n "component": require('@/pages/b/c').default,\n "name": "b_c",\n "meta": {},\n "count": 14\n },\n {\n "path": "/b/:id",\n "component": require('@/pages/b/@id').default,\n "name": "b__id",\n "meta": {},\n "count": 13\n },\n {\n "path": "/b",\n "component": require('@/pages/b/index').default,\n "name": "b_index",\n "meta": {},\n "count": 7\n }\n ]\n },\n {\n "path": "/",\n "component": require('@/pages/index').default,\n "name": "index",\n "meta": {},\n "count": 5\n },\n {\n "path": "/:pathMatch(.*)",\n "component": require('@/pages/*').default,\n "name": "FUZZYMATCH",\n "meta": {},\n "count": 3\n }\n ]\n }\n]\n
需要注意的是,满足以下任意规则的文件不会被注册为路由:
.vue .jsx
文件components
目录中的文件Fes.js 里约定以 @
开头的文件或文件夹映射为动态路由。 比如:
src/pages/users/@id.vue
会成为 /users/:id
src/pages/users/@id/settings.vue
会成为 /users/:id/settings
Fes.js 里约定目录下有 layout.vue
时会生成嵌套路由,以 layout.vue
为该目录的公共父组件,layout.vue
中必须实现 RouterView
比如以下目录结构:
pages\n└── users\n ├── layout.vue\n ├── index.vue\n └── list.vue\n
会生成路由:
[\n { \n path: '/users', component: require('@/pages/users/layout').default,\n children: [\n { path: '/users', component: require('@/pages/users/index').default },\n { path: '/users/list', component: require('@/pages/users/list').default },\n ]\n }\n]\n
比如以下目录结构:
pages\n├── index.vue # 根路由页面 路径为 /\n└── *.vue # 模糊匹配 路径为 *\n
会生成路由:
[\n { \n path: '/', component: require('@/pages/index').default, count: 5\n },\n {\n path: '/:pathMatch(.*)', component: require('@/pages/**').default, count: 3\n }\n]\n
这样,如果访问 /foo
,/
不能匹配,会 fallback 到 *
路由,通过 src/pages/*.vue
进行渲染。
我们在定义路由时可以配置meta
字段,用来记录一些跟路由相关的信息:
const router = new VueRouter({\n routes: [\n {\n path: '/foo',\n component: Foo,\n children: [\n {\n path: 'bar',\n component: Bar,\n // a meta field\n meta: { requiresAuth: true }\n }\n ]\n }\n ]\n})\n
接下来我们来配置 meta
:
则编译后的路由配置为:
[\n { \n path: '/a', \n component: require('@/pages/a').default, \n meta: {\n "name": "store",\n "title": "vuex测试"\n }\n },\n]\n
可以看到,编译后路由都会有 count
属性,这是我们根据精准匹配优先算法原则设计出路由排名算法,对匹配到的路由打分:
/list
)再加3分/:orderId
)再加2分/
)再1分*
)匹配到的减去1分当我们跳转路由时,如果 URL 匹配到多个路由,则选择分数最高的路由。
<template>\n <router-link to="/home">Home</router-link>\n</template>\n
import { useRouter } from '@fesjs/fes';\n\nexport default {\n setup(){\n const router = useRouter();\n // 这三种形式是等价的\n router.push('/users/posva#bio')\n router.push({ path: '/users/posva', hash: '#bio' })\n router.push({ name: 'users', params: { username: 'posva' }, hash: '#bio' })\n // 只改变 hash\n router.push({ hash: '#bio' })\n // 只改变 query\n router.push({ query: { page: '2' } })\n // 只改变 param\n router.push({ params: { username: 'jolyne' } })\n\n // 跳转到上一个路由\n router.goBack();\n\n // \b跳转到前一个历史记录\n router.go(1);\n\n // 替换历史堆栈中的记录\n router.replace('/new');\n }\n}\n\n