前言

  1. Boss API:http://113.31.105.128/boss/doc.html#/home
  2. Front API:http://113.31.105.128/front/doc.html#/home
  3. 前台地址:http://edufront.lagou.com/#/
  4. 后台地址:http://eduboss.lagou.com/#/

    01-使用VueCLI创建项目

  • vue create edu-boss-fed
    • 教育管理后台

image.png

  • TS => class-style component syntax

image.png

02-加入Git版本管理

image.png

  1. # -u 相当于设置上流服务器
  2. git push -u origin master
  3. # 效果相同
  4. git push origin master ; git branch --set-upstream master origin/master

03-初始目录结构说明

  1. ## .browserslistrc
  2. # 1% 的人用的浏览器也要做兼容
  3. > 1%
  4. # 兼容到最新的2个版本
  5. last 2 versions
  6. not dead
  7. ## .editorconfig 编辑器的配置信息
  8. [*.{js,jsx,ts,tsx,vue}]
  9. indent_style = space
  10. indent_size = 2
  11. trim_trailing_whitespace = true
  12. insert_final_newline = true

04-调整初始目录结构

  • 删除初始化的默认文件
  • 新增调整我们需要的目录结构
    • utils:放工具函数
    • styles
    • services:封装接口

      05-TS-环境说明

      在 Vue 项目中启用 Typescript 支持,两种方式:

  1. 全新项目:使用 Vue CLI 脚手架创建,并选择 TS
  2. 已有项目:添加 Vue 官方配置的 Typescript 适配插件
    • 使用 @vue/cli 安装 TS 插件
    • vue add @vue/typescript

06-TS-相关配置说明

i-TypeScript 相关的依赖项

dependencies 依赖:

依赖项 说明
vue-class-component 使用 Class 写 Vue 组件
vue-property-decorator 在 Class 语法基础之上提供了一些辅助装饰器

devDependencies 依赖:

依赖项 说明
@typescript-eslint/eslint-plugin 使用 ESLint 校验 TypesScript 代码
@typescript-eslint/parser 将 TypeScript 转为 AST 供 ESLint 校验使用
@vue/cli-plugin-typescript 调度 TypeScript 和 ESLint 相关插件,使用 TypeScript + ts-loader + fork-ts-checker-webpack-plugin 进行更快的类型检查
@vue/eslint-config-typescript 兼容 ESLint 的 TypeScript 校验规则
typescript TypeScript 编译器,提供类型校验和转换 JavaScript 的功能

ii-TypeScript 配置文件 tsconfig.json

iii-shims-vue.d.ts

  1. // 用于 TypeScript 识别 .vue 文件模块
  2. // .vue 文件模块都按 VueConstructor<vue> 类型识别处理
  3. declare module '*.vue' {
  4. import Vue from 'vue'
  5. export default Vue
  6. }

iv-shims-tsx.d.ts

  1. // 为 jsx 组件模板补充类型说明
  2. import Vue, { VNode } from 'vue'
  3. declare global {
  4. namespace JSX {
  5. // tslint:disable no-empty-interface
  6. interface Element extends VNode {}
  7. // tslint:disable no-empty-interface
  8. interface ElementClass extends Vue {}
  9. interface IntrinsicElements {
  10. [elem: string]: any;
  11. }
  12. }
  13. }

07-TS-使用OptionsAPI定义Vue组件

image.png

08-TS-使用ClassAPIs定义Vue组件

参考文档:https://class-component.vuejs.org/
image.png

09-TS-关于装饰器语法

function testable(target) { target.isTestable = true; }

MyTestableClass.isTestable // true

  1. Class MyTestableClass 作为参数传给函数 testable,这里给类赋值了静态属性 MyTestableClass.isTestable
  2. ```javascript
  3. @decorator
  4. class A {}
  5. // 等同于
  6. class A {}
  7. A = decorator(A) || A;

装饰器是一个对类进行处理的函数,装饰器函数的第一个参数就是类

10-TS-使用VuePropertyDecorator创建Vue组件

image.png
image.png

  1. Options APIs
    1. export default Vue.extend({ … })
  2. Class APIs(包含 @Component)
  3. Class APIs + decorator(@Prop等)

建议:只用 Options APIs,因为装饰器语法还没正式发布

12-代码格式规范-介绍

本项目使用的是 JavaScript Standard Style,特点是规则相对宽松,以下是它的部分规则:
image.png

13- 代码格式规范-项目中的代码规范说明

  1. module.exports = {
  2. root: true,
  3. env: {
  4. node: true
  5. },
  6. // 使用插件的编码规则
  7. extends: [
  8. 'plugin:vue/essential',
  9. '@vue/standard',
  10. '@vue/typescript/recommended'
  11. ],
  12. parserOptions: {
  13. ecmaVersion: 2020
  14. },
  15. // 自定义编码校验规则
  16. rules: {
  17. 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
  18. 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  19. }
  20. }
  • eslint-plugin-vue
  • @vue/eslint-config-standard
  • @vue/eslint-config-typescript

    14-代码格式规范-自定义校验规则

  • ESLint 的配置规则

  • ESLint 规则文档
  • TypeScript 结合 ESLint 的规则文档
  • 要让规则生效

    1. 重启服务
    2. 删除 node_modules/.cache 下的缓存
      1. rules: {
      2. 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
      3. 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
      4. 'semi': 'off'
      5. // 'semi': ['error', 'always']
      6. }

      15-导入Element组件库

  • npm i element-ui -S

    16-样式处理

    1. src/styles
    2. |-- index.scss # 全局样式,需要在 main.js 中导入
    3. |-- mixin.scss # 重复的公共样式,用于 mixin 混入
    4. |-- reset.scss # 重置基础样式
    5. |-- variables.scss #

    variables.scss ```css $primary-color: #40586F; $success-color: #51cf66; $warning-color: #fcc419; $danger-color: #ff6b6b; $info-color: #868e96; // #22b8cf;

$body-bg: #E9EEF3; // #f5f5f9;

$sidebar-bg: #F8F9FB; $navbar-bg: #F8F9FB;

$font-family: system-ui, -apple-system, “Segoe UI”, Roboto, Helvetica, Arial, sans-serif;

  1. index.scss
  2. ```css
  3. @import './variables.scss';
  4. // custom element theme
  5. $--color-primary: $primary-color;
  6. $--color-success: $success-color;
  7. $--color-warning: $warning-color;
  8. $--color-danger: $danger-color;
  9. $--color-info: $info-color;
  10. // change font path, required
  11. $--font-path: '~element-ui/lib/theme-chalk/fonts';
  12. // import element default theme
  13. @import '~element-ui/packages/theme-chalk/src/index';

17-样式处理-共享全局样式变量

每次使用都要导入,比较麻烦

  1. <style lang="scss" scoped>
  2. @import "~@/styles/variables.scss";
  3. .text {
  4. color: $success-color
  5. }
  6. </style>

将指定样式文件全局混入,在每个组件中都可以使用,不用 import

  1. module.exports = {
  2. css: {
  3. loaderOptions: {
  4. scss: {
  5. prependData: '@import "~@/styles/variables.scss";'
  6. }
  7. }
  8. }
  9. }

18-接口处理-配置后端代理

数据接口

  • http://eduboss.lagou.com
  • http://edufront.lagou.com
    1. proxy: {
    2. '/boss': {
    3. target: 'http://eduboss.lagou.com',
    4. changeOrigin: true // 把请求中的 host 配置为 target
    5. }
    6. }

    19-接口处理-封装请求模块

    ```javascript import axios from ‘axios’

const request = axios.create({ // 配置选项 })

// 请求拦截器

// 响应拦截器

export default request

  1. <a name="prJXo"></a>
  2. ## 20-布局-初始化路由组件
  3. | **路径** | **说明** |
  4. | --- | --- |
  5. | / | 首页 |
  6. | /login | 用户登录 |
  7. | /role | 角色管理 |
  8. | /menu | 菜单管理 |
  9. | /resource | 资源管理 |
  10. | /course | 课程管理 |
  11. | /user | 用户管理 |
  12. | /advert | 广告管理 |
  13. | /advert-space | 广告位管理 |
  14. ```bash
  15. src/views
  16. |--home
  17. |--index.vue
  18. |--login
  19. |--index.vue
  20. |--role
  21. |--index.vue
  22. |--menu
  23. |--index.vue
  1. {
  2. path: '/login',
  3. name: 'login',
  4. component: () => import(/* webpackChunkName: 'login' */ '@/views/login/index.vue')
  5. },

webpackChunkName 给打包的文件取个名字

21-布局-Layout和嵌套路由

/src/layout/index.vue

22-布局-Container布局容器

  • 使用 Element 的布局容器组件
  • height: 100vh; 获得 100% 的高度 ```css .el-header { background-color: #B3C0D1; }

.el-aside { background-color: #D3DCE6; height: 100vh; }

.el-main { background-color: #E9EEF3; }

  1. <a name="yMfNI"></a>
  2. ## 23-布局-侧边栏菜单
  3. - el-menu
  4. <a name="8UGsi"></a>
  5. ## 24-布局-头部Header
  6. - el-breadcrumb
  7. - el-dropdown
  8. - el-avatar
  9. <a name="KIMQk"></a>
  10. ## 25-登录-页面布局
  11. - el-form
  12. <a name="JpVjz"></a>
  13. ## 26-登录-登录接口测试
  14. - 接口文档:[http://113.31.105.128/front/doc.html#/home](http://113.31.105.128/front/doc.html#/home)
  15. - 该站点即可测试登录接口
  16. - phone: 15510792995
  17. - password: 111111
  18. - Postman 测试接口
  19. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/2960272/1607308923861-4a1a96da-29e1-4371-96fe-51d0761bbd5d.png#align=left&display=inline&height=582&margin=%5Bobject%20Object%5D&name=image.png&originHeight=582&originWidth=1047&size=78696&status=done&style=none&width=1047)
  20. <a name="NW5Qo"></a>
  21. ## 27-登录-请求登录
  22. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/2960272/1607310342606-1bf18b59-f218-4980-bc27-1bc419aaa06f.png#align=left&display=inline&height=348&margin=%5Bobject%20Object%5D&name=image.png&originHeight=348&originWidth=547&size=41379&status=done&style=none&width=547)<br />axios 设置 TypeScript Type
  23. ```javascript
  24. import axios, { AxiosInstance } from 'axios'
  25. const request: AxiosInstance = axios.create({
  26. // 配置选项
  27. })

28-登录-处理请求结果

  • $message

    29-登录-请求期间禁用按钮点击

  • el-button

    • loading

      30-登录-表单验证

      pattern 写正则表达式
      1. rules: {
      2. phone: [
      3. { require: true, message: '请输入手机号', trigger: 'blur' },
      4. // 1开头,后面跟10位数字
      5. { pattern: /^1\d{10}$/, message: '请输入正确的手机号', trigger: 'blur' },
      6. ]
      7. }
      TypeScript Type,查看类型定义
  • F12

  • Command + Click

image.png

31-登录-封装请求方法

src/utils/request.ts

  1. import axios, { AxiosInstance } from 'axios'
  2. const request: AxiosInstance = axios.create({
  3. // 配置选项
  4. })
  5. // 请求拦截器
  6. // 响应拦截器
  7. export default request

src/services/user.ts

  1. import request from '@/utils/request'
  2. import qs from 'qs'
  3. interface User {
  4. phone: string;
  5. password: string;
  6. }
  7. export const login = (data: User) => {
  8. return request({
  9. method: 'POST',
  10. url: '/front/user/login',
  11. headers: { 'content-type': 'application/x-www-form-urlencoded' },
  12. data: qs.stringify(data)
  13. })
  14. }

src/views/login/index.vue

  1. const { data } = await login(this.form)

32-登录-关于请求体data和ContentType的问题

axios 跟根据数据类型会自动设置 content-type

  • qs.stringfy(data) => application/x-www-form-urlencoded
  • FormaData 对象 => multipart/form-data
  • 普通对象 => application/json

    33-身份认证-把登录状态存储到Vuex容器中

  1. 登录成功,在 Vuex 中存储登录信息
    1. localStorage
  2. 在路由拦截器中判断登录信息
    1. state: {
    2. user: JSON.parse(window.localStorage.getItem('user') || 'null')
    3. },
    4. mutations: {
    5. setUser (state, payload) {
    6. state.user = JSON.parse(payload)
    7. window.localStorage.setItem('user', payload)
    8. }
    9. },

    34-身份认证-校验页面访问权限

    image.png

    35-身份认证-测试获取当前登录用户信息接口

    在 Postman 中给文件夹下的所有请求添加 Header
    image.png

    36-身份认证-登录成功跳转回原来页面

    image.png

    37-身份认证-展示当前登录用户信息

    设置头像,访问本地图片
    image.png

    38-身份认证-使用请求拦截器统一设置Token

    image.png

    39-身份认证-用户退出

    image.png