import{_ as t,r as o,o as c,c as l,b as n,d as s,a as e,f as p}from"./app.89d27141.js";const i={},r=n("h1",{id:"路由",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#路由","aria-hidden":"true"},"#"),s(" 路由")],-1),u=n("code",null,"Vue Router",-1),d={href:"https://next.router.vuejs.org/",target:"_blank",rel:"noopener noreferrer"},k=p(`

路由配置

在配置文件 .fes.js中通过 router 进行配置。

export default {
    router: {
        routes: [],
        mode: 'hash',
    },
};

routes

`,4),v=n("code",null,"routes",-1),m={href:"https://next.router.vuejs.org/zh/guide/",target:"_blank",rel:"noopener noreferrer"},b=n("h3",{id:"mode",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#mode","aria-hidden":"true"},"#"),s(" mode")],-1),h=n("p",null,"创建历史记录的类型:",-1),g=n("strong",null,"history",-1),y={href:"https://next.router.vuejs.org/zh/api/#createwebhistory",target:"_blank",rel:"noopener noreferrer"},f=n("strong",null,"hash",-1),_={href:"https://next.router.vuejs.org/zh/api/#createWebHashHistory",target:"_blank",rel:"noopener noreferrer"},x=n("strong",null,"memory",-1),j={href:"https://next.router.vuejs.org/zh/api/#createWebHashHistory",target:"_blank",rel:"noopener noreferrer"},q=p(`

默认是hash模式。

约定式路由

约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。

约定规范

比如以下文件结构:

pages
├── index.vue         # 根路由页面 路径为 /
├── [...slug].vue     # 模糊匹配 路径为 /:slug(.*)
├── a.vue             # 路径 /a
├── b                 # 文件夹b
│   ├── index.vue     # 路径 /b
│   ├── [slug].vue    # 动态路由 /b/:slug
│   ├── c.vue         # 路径 /b/c
│   └── layout.vue    # /b 路径下所有页面公共的布局组件
└── layout.vue        # 根路由下所有页面共用的布局组件

编译后会得到以下路由配置:

[
    {
        path: '/',
        component: require('@/pages/layout').default,
        count: 5,
        children: [
            {
                path: '/a',
                component: require('@/pages/a').default,
                name: 'a',
                meta: {},
                count: 7,
            },
            {
                path: '/b',
                component: require('@/pages/b/layout').default,
                count: 7,
                children: [
                    {
                        path: '/b/c',
                        component: require('@/pages/b/c').default,
                        name: 'b_c',
                        meta: {},
                        count: 14,
                    },
                    {
                        path: '/b/:id',
                        component: require('@/pages/b/@id').default,
                        name: 'b__id',
                        meta: {},
                        count: 13,
                    },
                    {
                        path: '/b',
                        component: require('@/pages/b/index').default,
                        name: 'b_index',
                        meta: {},
                        count: 7,
                    },
                ],
            },
            {
                path: '/',
                component: require('@/pages/index').default,
                name: 'index',
                meta: {},
                count: 5,
            },
            {
                path: '/:pathMatch(.*)',
                component: require('@/pages/*').default,
                name: 'FUZZYMATCH',
                meta: {},
                count: 3,
            },
        ],
    },
];

需要注意的是,满足以下任意规则的文件不会被注册为路由

动态路由

Fes.js 里约定名称为 [slug]格式的文件或文件夹映射为动态路由。 比如:

注意

@slug形式下版本会弃用,请替换为[slug]~

模糊匹配

Fes.js 里约定名称为 [...slug]格式的文件或文件夹映射为动态路由中的模糊匹配形式。 比如:

注意

*形式下版本会弃用,请替换为[...slug]~

嵌套路由

Fes.js 里约定目录下有 layout.vue 时会生成嵌套路由,以 layout.vue 为该目录的公共父组件,layout.vue 中必须实现 RouterView

比如以下目录结构:

pages
└── users
    ├── layout.vue
    ├── index.vue
    └── list.vue

会生成路由:

[
    {
        path: '/users',
        component: require('@/pages/users/layout').default,
        children: [
            { path: '/users', component: require('@/pages/users/index').default },
            { path: '/users/list', component: require('@/pages/users/list').default },
        ],
    },
];

模糊匹配

`,25),E=n("code",null,"*",-1),w={href:"https://next.router.vuejs.org/zh/guide/essentials/dynamic-matching.html#%E6%8D%95%E8%8E%B7%E6%89%80%E6%9C%89%E8%B7%AF%E7%94%B1%E6%88%96-404-not-found-%E8%B7%AF%E7%94%B1",target:"_blank",rel:"noopener noreferrer"},B=p(`

比如以下目录结构:

pages
├── index.vue         # 根路由页面 路径为 /
└── *.vue             # 模糊匹配 路径为 *

会生成路由:

[
    {
        path: '/',
        component: require('@/pages/index').default,
        count: 5,
    },
    {
        path: '/:pathMatch(.*)',
        component: require('@/pages/**').default,
        count: 3,
    },
];

这样,如果访问 /foo/ 不能匹配,会 fallback 到 * 路由,通过 src/pages/*.vue 进行渲染。

智能路由

可以看到,编译后路由都会有 count 属性,这是我们根据精准匹配优先算法原则设计出路由排名算法,对匹配到的路由打分:

当我们跳转路由时,如果 URL 匹配到多个路由,则选择分数最高的路由。

扩展路由元信息

我们在定义路由时可以配置meta字段,用来记录一些跟路由相关的信息:

const router = new VueRouter({
    routes: [
        {
            path: '/foo',
            component: Foo,
            children: [
                {
                    path: 'bar',
                    component: Bar,
                    // a meta field
                    meta: { requiresAuth: true },
                },
            ],
        },
    ],
});

我们使用defineRouteMeta 配置 meta

import { defineRouteMeta } from '@fesjs/fes';
defineRouteMeta({
    name: 'store',
    title: 'vuex测试',
});

当然在单文件组件中,还可以通过<config></config>配置 meta

<config>
{
    "name": "store",
    "title": "vuex测试"
}
</config>

提示

推荐使用defineRouteMete,有更好的提示。

路由元信息在编译后会附加到路由配置中:

[
    {
        path: '/a',
        component: require('@/pages/a').default,
        meta: {
            "name": "store",
            "title": "vuex测试"
        }
    },
]




 
 
 
 


路由跳转

`,20),R={href:"https://next.router.vuejs.org/zh/guide/essentials/navigation.html#%E6%9B%BF%E6%8D%A2%E5%BD%93%E5%89%8D%E4%BD%8D%E7%BD%AE",target:"_blank",rel:"noopener noreferrer"},V=p(`

声明式

<template>
    <router-link to="/home">Home</router-link>
</template>

命令式

`,3),F=n("code",null,"router",-1),H={href:"https://next.router.vuejs.org/zh/api/#router-%E6%96%B9%E6%B3%95",target:"_blank",rel:"noopener noreferrer"},M=p(`
import { useRouter } from '@fesjs/fes';

export default {
    setup() {
        const router = useRouter();
        // 这三种形式是等价的
        router.push('/users/posva#bio');
        router.push({ path: '/users/posva', hash: '#bio' });
        router.push({ name: 'users', params: { username: 'posva' }, hash: '#bio' });
        // 只改变 hash
        router.push({ hash: '#bio' });
        // 只改变 query
        router.push({ query: { page: '2' } });
        // 只改变 param
        router.push({ params: { username: 'jolyne' } });

        // 跳转到上一个路由
        router.goBack();

        // \b跳转到前一个历史记录
        router.go(1);

        // 替换历史堆栈中的记录
        router.replace('/new');
    },
};
`,1);function z(A,D){const a=o("ExternalLinkIcon");return c(),l("div",null,[r,n("p",null,[s("像 Vue 、React 这类框架是用组件化搭建页面,路由解决的是路径到组件的匹配问题。Fes.js 基于 "),u,s(" 实现的路由,想了解更多的同学可以看看"),n("a",d,[s("官方文档"),e(a)]),s("。")]),k,n("p",null,[v,s(" 是配置添加到路由的初始路由列表,格式为路由信息的数组。具体使用参考 "),n("a",m,[s("Vue Router 文档"),e(a)]),s(" 中关于路由配置、路由匹配相关内容。")]),b,h,n("ul",null,[n("li",null,[g,s(",对应 "),n("a",y,[s("createWebHistory"),e(a)])]),n("li",null,[f,s(",对应 "),n("a",_,[s("createWebHashHistory"),e(a)])]),n("li",null,[x,s(",对应 "),n("a",j,[s("createMemoryHistory"),e(a)])])]),q,n("p",null,[s("Fes.js 下约定文件名为 "),E,s(" 的路由是模糊匹配路由,可以用此特性实现 "),n("a",w,[s("404 路由"),e(a)]),s("。")]),B,n("p",null,[s("想学习更多,可以查看 "),n("a",R,[s("Vue Router 官方文档"),e(a)]),s("。")]),V,n("p",null,[s("页面跳转 API 由 "),F,s(" 实例提供,查看 "),n("a",H,[s("Vue Rouer 文档"),e(a)]),s("了解更多。")]),M])}const N=t(i,[["render",z],["__file","route.html.vue"]]);export{N as default};