13.1 搭建项目框架和页面结构
搭建项目框架从 Vue3 的脚手架开始,在生成的默认项目的基础上添加自定义配置。这些配置在本书第 5 章和第 7 章均有介绍,如不熟悉可从对应章节中查阅。
13.1.1 使用脚手架创建项目、安装依赖
确保电脑中安装了 Node.js(版本不低于 v16),我们使用命令创建项目。
(1)在电脑终端执行以下命令:
$ npm create vue@3
命令执行后会提示输入项目创建选项,选择如下:
- 项目名称:jueblog-frontend。
- 选择集成的依赖:TypeScript、JSX、Vue Router、Pinia。
等待项目生成,生成后安装项目默认依赖包。
(2)用 VScode 编辑器打开项目,安装项目依赖并运行。
执行 “code jueblog-frontend” 命令可以快速启动 VScode 编辑器并打开项目,然后在 VScode 的终端中执行以下命令:
$ yarn # 安装依赖
$ yarn run dev # 运行项目
运行后可以看到 Vue3 默认的欢迎页面,表示项目启动成功。默认依赖中不包含请求库、UI 框架等,我们还需要安装其他依赖。
(3)安装 UI 框架、请求库等其他必要的第三方依赖:
$ yarn add element-plus less axios dayjs
上方命令安装的几个依赖其各自的作用如下:
- element-plus:基于 Vue3 的 UI 组件库。
- less:让项目支持用 Less 语法编写样式。
- axios:请求库,封装全局统一的请求方法。
- dayjs:时间处理函数。
组件库 element-plus 需要在入口文件 src/main.ts 下注册,添加代码如下:
// src/main.ts
import ElementPlus from 'element-plus'
...
app.use(ElementPlus);
13.1.2 修改项目目录结构、添加基础配置
默认生成的项目目录结构基本够用,但我们还会拓展其他的功能,因此需要一个更加规范统一的目录结构来应对大部分的场景。我们主要修改 src 源码目录下的结构,修改结果如下:
- assets:静态资源目录,主要存放图片、文字。
- components:组件目录,存放公共组件。
- router:路由目录,存放路由的配置。
- stores:状态管理目录,存放 Pinia 仓库。
- views:页面目录,存放页面级别的组件。
- utils:工具函数目录,存放自定义的函数。
- styles:样式目录,存放全局样式文件。
- request:请求目录,存放 axios 全局请求对象。
- App.vue:根组件,页面最外层的组件。
- main.ts:入口文件,在这里创建 Vue App。
基于上方的目录结构,我们来添加一些基本的项目配置。
1. 添加样式配置
处理样式时统一用 Less 代替 CSS,步骤如下:
(1)在 styles 目录下创建 main.less 文件,用于定义全局样式。
该文件中可以定义全局 Less 变量和全局生效的样式,还可以加载其他的 Less 或 Css 文件。我们在入口文件中注册了 ElementPlus 框架,但是没有引入样式,可以在该文件顶部引入:
// main.less
@import "element-plus/dist/index.css";
一般在全局样式中,会统一修改某些元素或 UI 组件的默认样式,我们添加代码如下:
html {
font-size: 12px;
}
body {
background: #f5f5f5;
}
a {
text-decoration: none;
color: var(--el-color-primary);
transition: 0.4s;
}
ul,
li {
list-style: none;
margin: 0;
padding: 0;
}
p {
margin: 0;
line-height: 22px;
}
除此之外,还会将使用频率较高的布局样式封装为公共类名,如下:
.fx {
display: flex;
align-items: center;
}
.fxt {
display: flex;
align-items: flex-start;
}
.fx-c {
.fx();
justify-content: center;
}
.fx-b {
.fx();
justify-content: space-between;
}
.fxt-c {
.fxt();
justify-content: center;
}
.fxt-b {
.fxt();
justify-content: space-between;
}
这样我们在使用 Flex 布局的时候,就可以直接使用上方代码中定义的类名了,减少重复样式编写。
(2)创建 styles/variable.css 文件用于自定义 CSS 变量。
CSS 变量是浏览器新支持的样式复用方式,极大地方便了像修改主题这类功能的实现。ElementPlus 也使用了 CSS 变量来定义主题配置。下面是我们定义的 CSS 变量:
:root {
--el-color-primary: #1e80ff; // 主颜色
--font-color1: #252933; // 文本颜色1
--font-color2: #515767; // 文本颜色2
--font-color3: #8a919f; // 文本颜色3
--bg-color1: #f7f8fa; // 背景颜色1
--bg-color2: #ecf5ff; // 背景颜色2
--border-color: #e4e6eb; // 边框颜色
--header-height: 60px; // 头部高度
}
代码中定义的 --el-color-primary 变量表示 ElementPlus 的主题色,定义之后会覆盖 ElementPlus 默认主题色,实现了自定义主题的效果。
将该文件在 main.less 中第二行引入后生效:
// main.less
@import "element-plus/dist/index.css";
@import "./variable.css";
(3)在入口文件中加载全局样式,添加代码如下:
// main.ts
import "./styles/main.less";
样式加载后,在页面中使用 ElementPlus 的组件,会发现 UI 已经生效。
(4)在 .vue 组件中使用 Less 定义局部样式。
组件中使用 Less 很简单,在 style 标签上添加以下标识。组件中可以直接使用 CSS 变量,如下:
<style lang="less">
span {
color: var(--el-color-primary);
}
</style>
2. 添加格式化配置
格式化配置主要是指 prettier 的配置,我们提供一个通用的配置文件。
提示:详细的 prettier 使用介绍以及代码规范相关知识,请阅读本书第 11 章的内容。
(1)创建 .prettierrc.json 配置文件,写入代码如下:
{
"singleQuote": true, // 使用单引号
"semi": false, // 结尾不使用分号
"arrowParens": "avoid",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"requirePragma": false,
"overrides": [
{
"files": ["*.json"],
"options": {
"parser": "json-stringify"
}
}
]
}
(2)在 VSCode 编辑器中搜索安装插件 “Prettier - Code formatter”。
搜索到的该插件界面如图所示,安装后即可使用编辑器格式化代码。
(3)配置保存文件时自动格式化:
如果没有配置过保存自动格式化,请点击编辑器左下角的设置图标,选择设置-> 打开设置,切换到 JSON 格式,并添加以下配置:
{
"editor.defaultFormatter": "esbenp.prettier-vscode", // 配置默认格式化方式
"editor.formatOnSave": true // 开启自动格式化
}
13.1.3 添加统一路由配置、统一请求配置
项目中通常一个路由代表一个页面,我们要把项目中单独的页面都配置成路由,才能实现页面切换的功能;页面交互时会调用接口,还要配置一个公共的请求对象,用于统一处理请求逻辑。
1. 配置路由
项目生成后创建了默认的路由文件 router/index.ts 并在入口文件中注册,我们需要修改该文件的代码,将其变成适合本项目的路由配置。
(1)将默认的创建路由代码重置如下:
// router/index.ts
import { createRouter, createWebHistory } from "vue-router";
import routes from "./routes";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
});
export default router;
(2)创建 router/routes.ts 文件,定义路由数组并导出,之后的所有路由配置都在该数组中定义:
const routes = [];
export default routes;
(3)创建首页组件 views/home/index.vue 并添加路由,代码如下:
// router/routes.ts
import HomeView from '@/views/home/index.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView,
}
],
现在访问路径 “/” 就会自动定位到首页组件了。
2. 配置请求
基于 axios 定义一个全局请求实例,并添加请求拦截器和响应拦截器,可以统一执行一些请求和响应的处理。
(1)创建 request/index.ts 文件,在代码中创建一个 axios 实例并导出:
import axios, { type AxiosInstance } from "axios";
const instance: AxiosInstance = axios.create({
baseURL: "https://xxxx",
timeout: 15000,
headers: {
"Content-Type": "application/json",
},
});
export default instance;
上方代码中的 baseURL 选项表示接口的基础 URL,要填写在第 13 章中发布的云函数的 URL 地址,这样才能请求到我们自己开发的接口。
(2)添加请求拦截器,在每次请求前自动添加请求头参数:
instance.interceptors.request.use((request) => {
request.headers.Authorization = "Bearer " + (localStorage.token || "");
return request;
});
代码中的 localStorage.token 存储的是登录接口返回的 token,将其添加到请求头 Authorization 上进行接口权限验证。
(3)添加响应拦截器,统一处理不同情况下的返回异常并提示,代码如下:
import { ElMessage } from "element-plus";
instance.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
if (error.response) {
let response = error.response;
if (response.status === 401) {
ElMessage.error("登录已过期,请重新登录");
localStorage.removeItem("token");
} else {
ElMessage.error(response.message);
}
} else {
ElMessage.error(error.message);
}
return Promise.reject(error);
}
);
上方代码中特别处理了返回 401 状态码的情况,此时表示登录验证失败,会提示我们重新登录。
13.1.4 初始化 Git 配置
项目初始化后没有集成 Git 仓库,需要我们手动配置。集成 Git 很简单,主要步骤如下:
(1)执行以下命令,生成本地 Git 仓库:
$ git init
默认生成的本地仓库分支为 main 分支。
(2)创建 .gitignore 文件,写入 Git 忽略的文件或目录,如下:
npm-debug.log*
yarn-debug.log*
yarn-error.log*
node_modules
.DS_Store
dist
.vscode/*
!.vscode/extensions.json
.idea
大多数情况下,Git 只会将源码文件纳入版本管理,一些自动生成的文件或文件夹会被排除在外(如 node_modules 目录和 dist 目录),将其写在 .gitignore 文件中就会自动被 Git 忽略。
(3)创建第一个提交,命令如下:
$ git add .
$ git commit -m 'feat: 初始化提交'
(4)在 GitHub 中新建一个仓库,名为 “jueblog-frontend”,然后在项目中关联此远程仓库。
假设创建后的仓库地址为 “https://github.com/ruidoc/jueblog-frontend”,关联方法如下:
$ git remote add origin https://github.com/ruidoc/jueblog-frontend
此时便添加了名为 origin 的远程仓库。
(5)推送本地仓库的 main 分支到远程仓库,如下:
$ git push -u origin main
(6)使用 “git cz” 命令代替 “git commit” 命令,规范提交信息。
命令 “git cz” 由工具 “cz-conventional-changelog” 提供,如果不熟悉请参考本书第 11 章。