Skip to content

13.1 搭建项目框架和页面结构

搭建项目框架从 Vue3 的脚手架开始,在生成的默认项目的基础上添加自定义配置。这些配置在本书第 5 章和第 7 章均有介绍,如不熟悉可从对应章节中查阅。

13.1.1 使用脚手架创建项目、安装依赖

确保电脑中安装了 Node.js(版本不低于 v16),我们使用命令创建项目。

(1)在电脑终端执行以下命令:

js
$ npm create vue@3

命令执行后会提示输入项目创建选项,选择如下:

  • 项目名称:jueblog-frontend。
  • 选择集成的依赖:TypeScript、JSX、Vue Router、Pinia。

等待项目生成,生成后安装项目默认依赖包。

(2)用 VScode 编辑器打开项目,安装项目依赖并运行。

执行 “code jueblog-frontend” 命令可以快速启动 VScode 编辑器并打开项目,然后在 VScode 的终端中执行以下命令:

sh
$ yarn # 安装依赖
$ yarn run dev # 运行项目

运行后可以看到 Vue3 默认的欢迎页面,表示项目启动成功。默认依赖中不包含请求库、UI 框架等,我们还需要安装其他依赖。

(3)安装 UI 框架、请求库等其他必要的第三方依赖:

sh
$ yarn add element-plus less axios dayjs

上方命令安装的几个依赖其各自的作用如下:

  • element-plus:基于 Vue3 的 UI 组件库。
  • less:让项目支持用 Less 语法编写样式。
  • axios:请求库,封装全局统一的请求方法。
  • dayjs:时间处理函数。

组件库 element-plus 需要在入口文件 src/main.ts 下注册,添加代码如下:

js
// 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 框架,但是没有引入样式,可以在该文件顶部引入:

less
// main.less
@import "element-plus/dist/index.css";

一般在全局样式中,会统一修改某些元素或 UI 组件的默认样式,我们添加代码如下:

less
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;
}

除此之外,还会将使用频率较高的布局样式封装为公共类名,如下:

less
.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 变量:

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 中第二行引入后生效:

less
// main.less
@import "element-plus/dist/index.css";
@import "./variable.css";

(3)在入口文件中加载全局样式,添加代码如下:

js
// main.ts
import "./styles/main.less";

样式加载后,在页面中使用 ElementPlus 的组件,会发现 UI 已经生效。

(4)在 .vue 组件中使用 Less 定义局部样式。

组件中使用 Less 很简单,在 style 标签上添加以下标识。组件中可以直接使用 CSS 变量,如下:

vue
<style lang="less">
span {
  color: var(--el-color-primary);
}
</style>

2. 添加格式化配置

格式化配置主要是指 prettier 的配置,我们提供一个通用的配置文件。

提示:详细的 prettier 使用介绍以及代码规范相关知识,请阅读本书第 11 章的内容。

(1)创建 .prettierrc.json 配置文件,写入代码如下:

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 格式,并添加以下配置:

json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode", // 配置默认格式化方式
  "editor.formatOnSave": true // 开启自动格式化
}

13.1.3 添加统一路由配置、统一请求配置

项目中通常一个路由代表一个页面,我们要把项目中单独的页面都配置成路由,才能实现页面切换的功能;页面交互时会调用接口,还要配置一个公共的请求对象,用于统一处理请求逻辑。

1. 配置路由

项目生成后创建了默认的路由文件 router/index.ts 并在入口文件中注册,我们需要修改该文件的代码,将其变成适合本项目的路由配置。

(1)将默认的创建路由代码重置如下:

js
// 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 文件,定义路由数组并导出,之后的所有路由配置都在该数组中定义:

js
const routes = [];
export default routes;

(3)创建首页组件 views/home/index.vue 并添加路由,代码如下:

js
// router/routes.ts
import HomeView from '@/views/home/index.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView,
  }
],

现在访问路径 “/” 就会自动定位到首页组件了。

2. 配置请求

基于 axios 定义一个全局请求实例,并添加请求拦截器和响应拦截器,可以统一执行一些请求和响应的处理。

(1)创建 request/index.ts 文件,在代码中创建一个 axios 实例并导出:

js
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)添加请求拦截器,在每次请求前自动添加请求头参数:

js
instance.interceptors.request.use((request) => {
  request.headers.Authorization = "Bearer " + (localStorage.token || "");
  return request;
});

代码中的 localStorage.token 存储的是登录接口返回的 token,将其添加到请求头 Authorization 上进行接口权限验证。

(3)添加响应拦截器,统一处理不同情况下的返回异常并提示,代码如下:

js
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 仓库:

sh
$ 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”,关联方法如下:

sh
$ git remote add origin https://github.com/ruidoc/jueblog-frontend

此时便添加了名为 origin 的远程仓库。

(5)推送本地仓库的 main 分支到远程仓库,如下:

sh
$ git push -u origin main

(6)使用 “git cz” 命令代替 “git commit” 命令,规范提交信息。

命令 “git cz” 由工具 “cz-conventional-changelog” 提供,如果不熟悉请参考本书第 11 章。