本阶段任务
- 需求分析
- Web 前端技术选型
- Web 前端项目初始化(形成自己的 Vue 前端万用模板开发)
- 前端基础页面开发
- 应用市场的主页(呈现各类已过审的APP)
- 应用详情页
- 创建模块(创建应用/题目/评分)
- 答题模块(应用答题/答题结果/查看当前用户的回答记录)
前端技术
- List item
- Vue 3 ( Vue-CLl 脚手架)
- Pinia 状态管理
- Axios 请求库
- Arco Design 组件库
- 前端工程化:ESLint+ Prettier+ TypeScript
- OpenAPl 前端代码生成
开发大致流程
前端项目初始化
使用 Vue-CLl 脚手架快速创建 Vue3 项目—在 market 文件夹中使用vue create market-frontend
快速生成可执行的前端工程;
页面布局开发
引入 Acro Design 组件库
支持多套布局开发
在实际应用网页的过程中,我们可以发现不是所有页面都能统一布局,比如用户登录注册页等页面不需要导航栏,因此模板需要多套布局能力。
实现思路:
- 使用 vue-router 自带的子路由机制,实现布局和嵌套路由。例如:用户相关的路由配置:
在 route.ts 文件中引入
{
path: "/user",
name: "用户",
component: UserLayout,
children: [
{
path: "/user/login",
name: "用户登录",
component: UserLoginPage,
},
{
path: "/user/register",
name: "用户注册",
component: UserRegisterPage,
},
],
},
- 在 App.vue 根页面文件,根据路由的路径选择是否使用全局基础布局:
<template>
<div id="app">
<template v-if="route.path.startsWith('/user')">
<router-view />
</template>
<template v-else>
<BasicLayout />
</template>
</div>
</template>
还可以有更优雅的方式,可以通过配置路由的 meta.layout 参数决定是否开启全局基础布局,或者给需要全局基础布局的页面指定component:BasicLayout
请求
- 使用请求工具类 Axios ,参考 Axios 官方文档,编写请求配置文件request.ts
const myAxios = axios.create({
baseURL: "http://localhost:8101",
timeout: 10000,
withCredentials: true,
});
其中 withCredentials:true
一定要写,否则无法在发请求时携带 Cookie,就无法完成登录。
request.ts 中还包括全局接口请求地址、超时时间、自定义请求响应拦截器等
- 使用 OpenAPI 工具自动生成请求代码
全局状态管理
全局状态管理:所有页面全局共享的变量,而非局限在某一个页面中,例如已登录用户信息(每个页面几乎都需要)。
- 引入 Pinia 状态管理库
- 定义user状态(存储、远程获取、修改):
export const useLoginUserStore = defineStore("counter", () => {
const loginUser = ref<API.LoginUserVO>({
userName: "未登录",
});
function setLoginUser(newLoginUser: API.LoginUserVO) {
loginUser.value = newLoginUser;
}
async function fetchLoginUser() {
const res = await getLoginUserUsingGet();
if (res.data.code === 0 && res.data.data) {
loginUser.value = res.data.data;
} else {
// loginUser.value = { userRole: ACCESS_ENUM.NOT_LOGIN };
setTimeout(() => {
// todo 重新获取用户信息失败,则重置登录状态
loginUser.value = {};
}, 5000);
}
}
return { loginUser, setLoginUser, fetchLoginUser };
});
状态的使用:
const loginUserStore = useLoginUserStore();
loginUserStore.fetchLoginUser();
{{ JSON.stringify(loginUserStore.loginUser) }}
全局权限管理
优点:能够灵活配置每个页面所需要的用户权限,由全局权限管理系统自动校验和拦截,而不需要在每个页面中编写权限校验代码,提高开发效率。
实现方案:
- 在路由配置文件,定义某个路由的访问权限
- 使用全局路由监听器,每次访问页面时,根据用户要访问页面的路由权限信息,判断用户是否有对应的访问权限,并进行相应的拦截处理(例如跳转到无权限提示页面)
前端页面
用户模块
登录、注册、管理页面(仅管理员可用)
管理模块
应用管理、题目管理、评分结果管理、答题记录管理
应用
应用主页、应用详情页
创建模块
- 先创建应用 — 创建应用页面(支持修改功能)
- 进入应用详情页,作者本人选择给该应用上传题目或上传评分结果 — 创建题目页面/创建评分页面 (支持修改功能)
- 分别上传题目和评分结果
判断是否为作者本人:
const loginUserStore = useLoginUserStore();
const loginUserId = loginUserStore. loginUser . id;
const isMy = computed(() => {
return loginUserId && loginUserId === data. value .userId;
});
computed
是一个用于定义计算属性的函数。计算属性是基于其他响应式数据源(如组件的 data 或 props)进行计算的属性。它们的值会被缓存,直到依赖的数据源发生变化时才会重新计算。这种机制不仅提高了性能,还使代码更加简洁和可维护。
答题模块
应用答题页面/答题结果页面/查看我的回答页面