锋选菁英招聘管理平台项目
一、项目架构搭建
1. vite搭建项目
Vite下一代的前端工具链,为开发提供极速响应。
-
创建项目
yarn create vite 填项目名 选vue 选Typescript
-
安装依赖
cd fxjy-admin yarn
-
启动项目
yarn dev
2.目录架构认识及改造
src api 管理异步请求方法 components 公共组件 layout 基本布局骨架 store 状态机 router 路由 utils 公共方法包 views 业务组件(页面) assets 静态资源(img、css) App.vue 根组件 main.ts 入口文件
3. vite配置路径别名@
-
vite.config.ts配置
... import { join } from "path"; export default defineConfig({ ... resolve: { alias: { "@": join(__dirname, "src"), }, }, });
-
根目录新建 tsconfig.json 配置
{ "compilerOptions": { "experimentalDecorators": true, "baseUrl": "./", "paths": { "@/*": ["src/*"], "components/*": ["src/components/*"], "assets/*": ["src/assets/*"], "views/*": ["src/views/*"], "common/*": ["src/common/*"] } }, "exclude": ["node_modules", "dist"] }
-
安装path的类型提示
yarn add @types/node
-
重启 vscode
4. AntDesign 组件库
-
安装组件库
yarn add ant-design-vue
-
按需导入辅助包
yarn add unplugin-vue-components --dev
-
修改vite.config.ts配置
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import Components from "unplugin-vue-components/vite"; import { AntDesignVueResolver } from "unplugin-vue-components/resolvers"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), Components({ resolvers: [AntDesignVueResolver()], }), ], ... });
-
在任意.vue组件中,直接使用组件,如App.vue
<script setup lang="ts"> </script> <template> <a-button type="primary">Primary Button</a-button> </template> <style scoped> </style>
5. 搭建主面板骨架
-
从antd-vue官方获取layout布局
不要照着代码敲,直接复制即可,然后只需要为a-layout容器添加高度
// src/layout/index.vue 主要的布局文件 <template> <a-layout style="min-height: 100vh"> <SiderMenu /> <a-layout> <a-layout-header style="background: #fff; padding: 0" /> <a-layout-content style="margin: 0 16px"> <a-breadcrumb style="margin: 16px 0"> <a-breadcrumb-item>User</a-breadcrumb-item> <a-breadcrumb-item>Bill</a-breadcrumb-item> </a-breadcrumb> <div :style="{ padding: '24px', background: '#fff', minHeight: '360px' }" > Bill is a cat. </div> </a-layout-content> <a-layout-footer style="text-align: center"> Ant Design ©2018 Created by Ant UED </a-layout-footer> </a-layout> </a-layout> </template> <script setup lang="ts"> import { PieChartOutlined, DesktopOutlined, UserOutlined, TeamOutlined, FileOutlined, } from "@ant-design/icons-vue"; import { ref } from "vue"; import SiderMenu from "./components/sider-menu.vue"; const collapsed = ref(false); const selectedKeys = ref(["1"]); </script> <style scoped> .logo { height: 32px; margin: 16px; background: rgba(255, 255, 255, 0.3); } .site-layout .site-layout-background { background: #fff; } [data-theme="dark"] .site-layout .site-layout-background { background: #141414; } </style>
-
App.vue引入 主界面的布局文件
<script setup lang="ts"> import MainLayout from "@/layout/index.vue"; </script> <template> <MainLayout /> </template> <style scoped></style>
-
查看浏览器,预览运行结果
二、VueRouter路由运用
2.1.路由基本配置
-
安装
默认安装的是vue-router@4,使用时需要注意版本号
yarn add vue-router
-
新建页面组件
└─views │ dashboard.vue 可视化图表页 ├─category 分类管理 │ list.vue │ pub.vue └─job 岗位管理 list.vue pub.vue
-
配置路由
// src/router/index.ts import { createRouter, createWebHashHistory } from "vue-router"; const router = createRouter({ history: createWebHashHistory(), routes: [ { path: "/", component: () => import("@/views/dashboard.vue"), }, { path: "/category/list", component: () => import("@/views/category/list.vue"), }, { path: "/category/pub", component: () => import("@/views/category/pub.vue"), }, ], }); export default router;
-
呈现路由组件
需要在MainLayout的内容区域添加一个RouterView组件,用来动态显示路由匹配到的组件。
-
通过手动修改地址栏地址,可以测试路由组件切换效果
2.2 动态渲染菜单
-
改造路由数据包
export const routes = [ { path: "/", component: () => import("@/views/dashboard.vue"), meta: { label: "数据可视化", icon: "area-chart-outlined", }, }, { path: "/category", component: () => import("@/views/category/index.vue"), meta: { label: "分类管理", icon: "area-chart-outlined", }, children: [ { path: "/category/list", component: () => import("@/views/category/list.vue"), meta: { label: "分类列表", }, }, { path: "/category/pub", component: () => import("@/views/category/pub.vue"), meta: { label: "发布分类", }, }, ], }, ]; const router = createRouter({ history: createWebHashHistory(), routes, });
-
单独拆分侧边菜单组件
考虑到代码的可维护性,我们将MainLayout中的侧边菜单逻辑交互单独拆分为一个组件
组件存放位置:/src/layout/components/side-menu.vue
-
在side-menu.vue中使用路由数据包动态渲染
<template> <a-layout-sider v-model:collapsed="collapsed" collapsible> <div class="logo" /> <a-menu v-model:selectedKeys="selectedKeys" theme="dark" mode="inline"> <template v-for="(item, index) in routes" :key="index"> <a-menu-item v-if="!item.children" :key="item.path"> <component :is="item.meta!.icon"></component> <span>{ { item.meta!.label }}</span> </a-menu-item> <a-sub-menu v-else :key="index"> <template #title> <span> <component :is="item.meta!.icon"></component> <span>{ { item.meta!.label }}</span> </span> </template> <a-menu-item v-for="child in item.children" :key="child.path">{ { item.meta!.label }}</a-menu-item> </a-sub-menu> </template> </a-menu> </a-layout-sider> </template> <script setup lang="ts"> import { ref } from "vue"; import { routes } from "@/router"; const collapsed = ref(false); const selectedKeys = ref(["1"]); </script> <style scoped></style>
-
通过useRouter触发路由切换
const router = useRouter(); const handleMenu = ({ key }: { key: string }) => { //此处的key是由menu组件点击事件提供 console.log(key); router.push(key); };
2.3 动态图标及路由跳转
-
安装
yarn add @ant-design/icons-vue
-
main.ts全局注册
import * as antIcons from "@ant-design/icons-vue"; const app = createApp(App); // 注册组件 Object.keys(antIcons).forEach((key: any) => { app.component(key, antIcons[key as keyof typeof antIcons]); }); // 添加到全局 app.config.globalProperties.$antIcons = antIcons;
-
动态组件
<component is="xxx">
2.4 面包屑交互
-
封装面包屑组件
封装面包屑组件
使用useRoute、结合watch监听,在面包屑组件中监听路由路径的变化
// src/layout/component/app-breadcrumb.vue <template> <a-breadcrumb> <a-breadcrumb-item>首页</a-breadcrumb-item> </a-breadcrumb> </template> <script setup lang="ts"> import { watch } from "vue"; import { useRoute } from "vue-router"; const route = useRoute(); watch( route, (newValue) => { console.log("路由发生变化了", newValue.path); } ); </script> <style scoped></style>
-
整合面包屑数据包
封装一个方法函数,将路由数据包,处理为【path--菜单名】的映射格式:
{
'/dashboard':'数据统计',
'/category':'分类管理',
'/category/list':'分类列表'
......
}</