第十五章:配置 vue-router

安装

pnpm add vue-router@4

一、创建路由配置

1.1、创建 src/router/routes/index.ts 文件,并进行路由配置

// src/router/routes/index.ts

import type { RouteRecordRaw } from 'vue-router'
import { DashboardOutlined, HomeOutlined } from '@ant-design/icons-vue'
import { LOGIN_NAME, PAGE_NOT_FOUND_NAME } from '../constant'

export const routesList: Array<RouteRecordRaw> = [
    {
        path: '/',
        name: 'Layout',
        redirect: '/dashboard/welcome',
        component: () => import('@/layout/layout.vue'), // 需要创建 src/layout/layout.vue 文件否则会报错
        meta: {
            title: '首页',
            fullPath: '/',
        },
        children: [
            {
                 path: '/dashboard',
                 name: 'Dashboard',
                 redirect: '/dashboard/welcome',
                 meta: {
                     title: '概览页',
                     fullPath: '/dashboard',
                     icon: DashboardOutlined,
                 },
                 children: [
                     {
                         path: 'welcome',
                         name: 'DashboardWelcome',
                         meta: {
                             title: '工作台',
                             fullPath: '/dashboard/welcome',
                             icon: HomeOutlined,
                         },
                         component: () => import('@/views/dashboard/welcome/welcome.vue'), // 需要创建 src/views/dashboard/welcome/welcome.vue 文件否则会报错
                     },
                 ],
            },
            {
                path: '/account',
                redirect: '/account/settings',
                name: 'Account',
                meta: {
                    title: '个人中心',
                    fullPath: '/account',
                    hideInMenu: true,
                },
               children: [
                   {
                        path: 'settings',
                        name: 'AccountSettings',
                        component: () => import('@/views/account/settings/settings.vue'),
                        meta: {
                            title: '个人设置',
                            fullPath: '/account/settings',
                        },
                   },
               ],
            },
        ],
    },
    {
        path: '/login',
        name: LOGIN_NAME,
        component: () => import('@/views/login/login.vue'),
        meta: {
            title: '登录',
        },
    },
    {
        path: '/:pathMatch(.*)*', // 捕获所有路由或 404 Not found 路由
        name: PAGE_NOT_FOUND_NAME,
        meta: {
            title: '404 Not found',
        },
        component: () => import('@/views/error/404.vue'), // 需要创建 src/views/error/404.vue 文件否则会报错
    }

];

1.2、创建 types/vue-router.d.ts 自定义路由配置项 meta: RouteMeta 的类型声明

// types/vue-router.d.ts

import type { RouteMeta as VRouteMeta } from 'vue-router'

declare module 'vue-router' {
    interface RouteMeta extends VRouteMeta {
        /** 标题 */
        title: string;

        /** 当前路由所在的完整路径, 用来实现登录后的重定向功能 */
        fullPath: string

        /** 
         * 菜单图标; antd 图标名称, 这是临时写法
         * TODO: 后期还要根据 antd icon 中提供的方法,进行自定义一些图标,但是需要注意的是,自定义图标后需要验证侧边栏菜单中的图标是否还能正常展示
         * 例如: antd 图标为 <StepBackwardOutlined />,那么 icon 属性的值则是:StepBackwardOutlined
         */
        icon?: any;

        /** 是否需要缓存 */
        keepAlive?: boolean

        /** 是否外链 */
        isExt?: boolean

        /**
         * 外链打开方式
         * 1: 新窗口打开
         * 2: 内嵌 iframe
         */
        extOpenMode?: 1 | 2

         /** 是否隐藏页面加载进度条 */
        hideProgressBar?: boolean;

        /**
         * 不在菜单中显示
         * 此属性只会控制侧边栏中的一级菜单是否展示,不会对子级菜单的是否展示进行控制
         * 如果要对子级菜单进行控制,请使用 hideChildrenInMenu 属性
         */
        hideInMenu?: boolean

        /**
         * 在菜单中隐藏子节点, 一般在 children 中有隐藏的子节点时,可以设置 hideChildrenInMenu: true 来只显示父级菜单名称
         * 例如: 父级菜单: 用户列表页 (/user/list) 路由配置中可以设置 hideChildrenInMenu: true,
         * 例如: 子级菜单: 用户详情页 (/user/list/1, /user/list/2, /user/list/3) 不会出现在菜单中
         */
        hideChildrenInMenu?: boolean

        /** 不在页面 header 中的面包屑导航中显示 */
        hideInBreadcrumb?: boolean

        /** 不在tab标签页中显示 */
        hideInTabs?: boolean

       
    }
}

1.3、创建 src/layout/layout.vue 文件

// src/layout/layout.vue

<script setup>

</script>

<template>
  <div class="mt-12px">layout/layout.vue</div>
  <router-view />
</template>

<style scoped>

</style>

1.4、创建 src/views/dashboard/welcome/welcome.vue 文件

// src/views/dashboard/welcome/welcome.vue

<script setup>

</script>

<template>
  <div class="mt-12px">
     工作台
 </div>
</template>

<style scoped>

</style>

1.5、创建 src/views/login/login.vue 文件

// src/views/login/login.vue

<script setup lang="ts">
import { message } from 'ant-design-vue'
import { ref } from 'vue'

const loading = ref(false)
const loginFormModel = ref({
    username: 'admin',
    password: 'a123456',
})

const handleSubmit = async () => {
    const { username, password } = loginFormModel.value
    if (username.trim() === '' || password.trim() === '') {
        return message.warning('用户名或密码不能为空!')
    }
     message.loading('登录中...', 0)
     loading.value = true
}
</script>

<template>
    <div class="login-box">
        <div class="login-logo">
            <img src="~@/assets/logo.svg" width="45">
            <h1 class="mb-0 ml-2 text-3xl font-bold">
                后台管理系统
            </h1>
        </div>

        <a-form layout="horizontal" :model="loginFormModel" @submit.prevent="handleSubmit">
            <a-form-item>
                <a-input v-model:value="loginFormModel.username" size="large" placeholder="admin">
                    <template #prefix>
                        <Icon icon="ant-design:user-outlined" />
                    </template>
                </a-input>
            </a-form-item>

            <a-form-item>
                <a-input
                    v-model:value="loginFormModel.password"
                    size="large"
                    type="password"
                    placeholder="a123456"
                    autocomplete="new-password"
                >
                    <template #prefix>
                        <Icon icon="ant-design:lock-outlined" />
                    </template>
                </a-input>
            </a-form-item>

            <a-form-item>
                <a-button type="primary" html-type="submit" size="large" :loading="loading" block>
                    登录
                </a-button>
            </a-form-item>
        </a-form>
    </div>
</template>

<style lang="less" scoped>
.login-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100vw;
    height: 100vh;
    padding-top: 240px;
    background: #fff;
    background-size: 100%;

    .login-logo {
        display: flex;
        align-items: center;
        margin-bottom: 30px;
    }

    :deep(.ant-form) {
        width: 400px;

        .ant-col {
            width: 100%;
        }

        .ant-form-item-label {
            padding-right: 6px;
        }
    }
}
</style>

1.6、创建 src/views/error/404.vue 文件

// src/views/error/404.vue

<script setup>

</script>

<template>
  <div class="mt-12px">src/views/error/404.vue</div>
</template>

<style scoped>

</style>

二、创建路由实例

2.1、创建 src/router/index.ts 文件,并进行实例化路由器

// src/router/index.ts

import type { App } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import { routesList } from './routes'

export const router = createRouter({
    // import.meta.env.BASE_URL
    history: createWebHashHistory(import.meta.env.BASE_URL),
    routes: routesList, // 将 1.1 中创建好的路由配置引入到这里
});

// 通过 setupRouter 函数将 router 实例传递给 app 应用
export async function setupRouter(app: App) {

    app.use(router)

     // 路由准备就绪后,路由插件帮我们做了如下操作:
    // 1、全局注册 RouterView 和 RouterLink 组件。
    // 2、添加全局 $router 和 $route 属性(可以在组件模板中使用)
    // 3、启用 useRouter() 和 useRoute() 组合式函数。
    // 4、触发路由器解析初始路由。
    await router.isReady()
}

export default router;

三、注册路由器插件(在 src/main.ts 中)

// src/main.ts

import { createApp } from 'vue'
const app = createApp(App)

// 挂载路由
async function setupAppRouter() {
  await setupRouter(app)

  // 路由准备就绪后才能挂载APP实例
  app.mount('#app')
}

setupAppRouter()

四、添加路由出口(在 src/App.vue 中)

// src/App.vue

<template>
    <!-- 采用 RouterView 插槽的方式设置路由出口,便于扩展其它功能 -->
    <router-view v-slot="{ Component }">
         <component :is="Component" />
    </router-view>
</template>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容