欢迎光临
我们一直在努力

前端单体项目搭建步骤

单体项目的前端搭建

做后端的朋友都知道,后端的工作不仅需要你精通后端,前端的知识也需要了解,有时候甚至需要自己搭建前端页面,这里我通过一个小项目(管理系统)展示单体项目的前端搭建步骤

下面这些步骤需要你懂一些vue3知识。

步骤一:构建项目

构建项目:

一般快速搭建项目我们使用vite搭建vue3项目

执行下面代码会下载最先的vite并用此构建项目

npm create vite@latest

在这里插入图片描述

起好项目名,选择合适框架和语言就可以了 在这里插入图片描述

我这里选了自动启动,点击网址就可以访问你自己构建的前端项目了。 在这里插入图片描述

网页是这样的

在这里插入图片描述

接下来我们使用vscode打开项目文件夹

在这里插入图片描述

我们把没用的东西删掉,例如style.css,HelloWorld.vue。

记住删掉style.css的时候,也要删除mian.js里面的对style.css的导入语句。HelloWorld.vue也是一样,它在App.vue中有使用

把App.vue删成这样就可以了

<script setup>
</script>

<template>
</template>

<style scoped>
</style>

OK,接下来就可以开始第二步了

步骤二:导入依赖

一般单体项目我们导入那几个基本的依赖就可以了

例如,这几个

"dependencies": {
"axios": "^1.13.2",
"element-plus": "^2.13.0",
"vue-router": "^4.6.4"
},

解释:

  • axios是发送异步请求的依赖
  • element-plus是一个组件库,简化开发的
  • vue-router是路由组件,用于控制路由和组件之间的跳转,非常重要。

其实对于element-plus也可以不引用,对于可以直接用ai生成组件来说,也可以不使用element-plus,毕竟样式ai也可以帮你生成。

版本不必过于讲究,这些版本是在vite.config.js文件中复制过来的。

命令如下

npm install axios
npm install element-plus
npm install vue-router

之后就是使用这些依赖了

axios

这个axios我们需要涉及到请求的发送,我们一般是先封装好一个request对象,在这个对象里我们可以对请求做以下提前处理,例如设置拦截器做token的保存

众所周知,前端页面就是配合后端使用的,前端发请求一般会出现跨域问题,这时候就需要配置反向代理了,在开发阶段我们在项目的vite.config.js中配置代理

代码如下

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

// https://vite.dev/config/
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:8081',
changeOrigin: true,
rewrite: (path) => path.replace(/^\\/api/, ''),
// 关键:配置代理处理所有方法,包括 OPTIONS
configure: (proxy, options) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log('代理请求:', req.method, req.url);
});
}
},
}
},
plugins: [
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})

例如我在src目录下创建一个utils目录,在utils目录下我们创建一个request.js文件

import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'

const request = axios.create({
baseURL: '/api',
timeout: 10000
})

// 请求拦截器
request.interceptors.request.use(
(config) => {
// 从localStorage获取token
const token = localStorage.getItem('token')
if (token) {
config.headers.authentication = token
}
return config
},
(error) => {
return Promise.reject(error)
}
)

// 响应拦截器
request.interceptors.response.use(
response => {
// 如果返回的是文件流,直接返回
if (response.config.responseType === 'blob') {
return response
}

const { code, message, data } = response.data

if (code === 200) {
return data
} else {
ElMessage.error(message || '请求失败')
return Promise.reject(new Error(message || '请求失败'))
}
},
error => {
if (error.response) {
const { status, data } = error.response

switch (status) {
case 401:
ElMessage.error('登录已过期,请重新登录')
localStorage.removeItem('token')
localStorage.removeItem('userInfo')
router.push('/login')
break
case 403:
ElMessage.error('没有权限访问')
break
case 404:
ElMessage.error('请求的资源不存在')
break
case 500:
ElMessage.error(data?.message || '服务器内部错误')
break
default:
ElMessage.error(data?.message || '请求失败')
}
} else if (error.request) {
ElMessage.error('网络错误,请检查网络连接')
} else {
ElMessage.error('请求配置错误')
}

return Promise.reject(error)
}
)

export default request

然后我们就可以在src目录下创建一个api目录,在api目录中我们可以对特定的组件分装好它需要的请求。

例如department.js

import request from '@/utils/request'

// 部门管理API
export default {
// 获取部门列表
getDepartmentList(params) {
return request({
url: '/department/list',
method: 'get',
params
})
},

// 获取部门详情
getDepartmentDetail(id) {
return request({
url: `/department/${id}`,
method: 'get'
})
},

// 新增部门
addDepartment(data) {
return request({
url: '/department',
method: 'post',
data
})
},

// 更新部门
updateDepartment(id, data) {
return request({
url: `/department/${id}`,
method: 'put',
data
})
},

// 删除部门
deleteDepartment(id) {
return request({
url: `/department/${id}`,
method: 'delete'
})
},

// 获取部门树结构
getDepartmentTree() {
return request({
url: '/department/tree',
method: 'get'
})
},

// 获取部门员工列表
getDepartmentEmployees(id) {
return request({
url: `/department/${id}/employees`,
method: 'get'
})
},

// 更新部门经理
updateDepartmentManager(deptId, empId) {
return request({
url: `/department/${deptId}/manager`,
method: 'put',
data: { managerId: empId }
})
}
}

axios大致需要做的就是两步:

  • 创建request.js,设置拦截器做token保存
  • 创建api.js,对请求做好封装(这一步可以在创建好组件之后再进行)

element-plus

使用element-plus的步骤,就是在main.js中引入全局样式,可注册所有图标,在vue中使用element-plus

代码如下

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'

const app = createApp(App)

// 注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}

app.use(ElementPlus)
app.mount('#app')

vue-router

设置路由配置,编写路由守卫

在src目录下创建一个router目录,然后在router目录下创建一个index.js文件

在index.js文件中编写路由配置,这时候我们还没有写组件,我们可以构思好组件,对于单体页面来说,一般需要一个主页面,在这个主页面中包括一个侧边栏或导航栏,通过这个导航栏我们可以跳转到指定组件,另外我们在完成了主界面后还可以设计一下登录页面。登录页面应该是和主页面同级的。可以覆盖主页面。

import { createRouter, createWebHistory } from 'vuerouter'

const routes = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/Login.vue')
},
{
path: '/',
name: 'Layout',
component: () => import('@/views/layout/Layout.vue'),
redirect: '/employee',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/Dashboard.vue'),
meta: { title: '首页' }
},
{
path: 'employee',
name: 'Employee',
component: () => import('@/views/employee/Employee.vue'),
meta: { title: '员工管理' }
},
{
path: 'employee/add',
name: 'EmployeeAdd',
component: () => import('@/views/employee/EmployeeForm.vue'),
meta: { title: '新增员工' }
},
{
path: 'employee/edit/:id',
name: 'EmployeeEdit',
component: () => import('@/views/employee/EmployeeForm.vue'),
meta: { title: '编辑员工' }
},
{
path: 'department',
name: 'Department',
component: () => import('@/views/department/Department.vue'),
meta: { title: '部门管理' }
},
{
path: 'position',
name: 'Position',
component: () => import('@/views/position/Position.vue'),
meta: { title: '岗位管理' }
},
{
path: 'attendance',
name: 'Attendance',
component: () => import('@/views/attendance/Attendance.vue'),
meta: { title: '考勤管理' }
},
{
path: 'salary',
name: 'Salary',
component: () => import('@/views/salary/Salary.vue'),
meta: { title: '薪酬管理' }
},
{
path: 'profile',
name: 'Profile',
component: () => import('@/views/profile/Profile.vue'),
meta: { title: '个人中心' }
}
]
}
]

const router = createRouter({
history: createWebHistory(),
routes
})

// 路由守卫
router.beforeEach((to, from, next) => {
//如果没有token或者是token过期直接跳转到登录页面
const isAuthenticated = localStorage.getItem('token')
console.log("taken: "+isAuthenticated);

if (to.name !== 'Login' && !isAuthenticated) {
next({ name: 'Login' })
}
else {
next()
}
})

export default router

编写完路由配置之后,我们需要在main.js中使用路由配置。

main.js完整如下

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'
//使用路由配置
import router from './router'

const app = createApp(App)

// 注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}

app.use(ElementPlus)
app.use(router)
app.mount('#app')

步骤三:实现各个页面

实现页面的步骤:

  • 先实现主页面,需要有侧边栏或导航栏

有侧边栏的主页面模版

<template>
<div class="layout-container">
<!– 侧边栏 –>
<el-menu
:default-active="activeMenu"
class="sidebar"
:collapse="isCollapse"
router
>

<div class="logo">
<h2 v-if="!isCollapse">人才管理系统</h2>
<h3 v-else>人才</h3>
</div>

<el-menu-item index="/dashboard">
<el-icon><House /></el-icon>
<span>首页</span>
</el-menu-item>

<el-sub-menu index="1">
<template #title>
<el-icon><User /></el-icon>
<span>人员管理</span>
</template>
<el-menu-item index="/employee">员工管理</el-menu-item>
<el-menu-item index="/department">部门管理</el-menu-item>
<el-menu-item index="/position">岗位管理</el-menu-item>
</el-sub-menu>

<el-sub-menu index="2">
<template #title>
<el-icon><Calendar /></el-icon>
<span>考勤管理</span>
</template>
<el-menu-item index="/attendance">考勤记录</el-menu-item>
<el-menu-item index="/attendance/statistics">考勤统计</el-menu-item>
</el-sub-menu>

<el-menu-item index="/salary">
<el-icon><Money /></el-icon>
<span>薪酬管理</span>
</el-menu-item>

<el-menu-item index="/profile">
<el-icon><Setting /></el-icon>
<span>个人中心</span>
</el-menu-item>
</el-menu>

<!– 主内容区 –>
<div class="main-content">
<!– 顶部导航栏 –>
<div class="header">
<div class="header-left">
<el-button type="text" @click="toggleSidebar" class="collapse-btn">
<el-icon><Fold v-if="!isCollapse" /><Expand v-else /></el-icon>
</el-button>
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="item in breadcrumbs" :key="item.path">
{{ item.meta?.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>

<div class="header-right">
<el-dropdown>
<span class="user-info">
<el-avatar :size="32" :src="userAvatar" />
<span class="username">{{ userName }}</span>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="goToProfile"
>
个人中心</el-dropdown-item
>

<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>

<!– 页面内容 –>
<div class="content-wrapper">
<router-view :key="$route.fullPath" />
</div>
</div>
</div>
</template>

<script setup>
import { ref, computed } from "vue";
import { useRouter, useRoute } from "vue-router";
import {
House,
User,
Calendar,
Money,
Setting,
Fold,
Expand,
} from "@element-plus/icons-vue";

const router = useRouter();
const route = useRoute();
const isCollapse = ref(false);

const activeMenu = computed(() => route.path);
const breadcrumbs = computed(() => {
const matched = route.matched.filter((item) => item.meta && item.meta.title);
return matched;
});

// 用户信息(这里先模拟)
const userName = ref("管理员");
const userAvatar = ref("");

const toggleSidebar = () => {
isCollapse.value = !isCollapse.value;
};

const goToProfile = () => {
router.push("/profile");
};

const logout = () => {
localStorage.removeItem("token");
router.push("/login");
};

import { watch } from "vue";

watch(
() => route.path,
(newPath) => {
console.log("路由已切换到:", newPath);
}
);
</script>

  • 然后就可以实现其他的组件了,这些可以交给ai,当然其实主界面也可以直接交给ai,同样快。
  • 最后可以去实现一下登录页面。

最后这个前端页面就实现了,按照这个步骤配合ai编程可以很快的搭建好一个单体系统的前端页面。

最后展现一下效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

项目的gitee地址

HH-HRMS: 人力资源管理系统

赞(0)
未经允许不得转载:171主机测评 » 前端单体项目搭建步骤
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址