^-^
CV | FE
Nest.js入门
怎么和Java那么像啊?
  1. 前置知识
  2. 安装与启动
  3. 文件结构
  4. 常用命令
  5. 练手之Session
  6. 中间件
  7. 上传下载文件
  8. 拦截器
  9. 管道

前置知识

IOC、DI(其实是一个东西啦)
类A依赖类B的一个常规表现通常是类A使用类B的Instance。
解决方法是使用IOC容器:

class A {
    name: string
    constructor(name: string) {
        this.name = name
    }
}


class C {
    name: string
    constructor(name: string) {
        this.name = name
    }
}
//中间件用于解耦
class Container {
    modeuls: any
    constructor() {
        this.modeuls = {}
    }
    provide(key: string, modeuls: any) {
        this.modeuls[key] = modeuls
    }
    get(key) {
        return this.modeuls[key]
    }
}

const mo = new Container()
mo.provide('a', new A('小满1'))
mo.provide('c', new C('小满2'))

class B {
    a: any
    c: any
    constructor(container: Container) {
        this.a = container.get('a')
        this.c = container.get('c')
    }
}
new B(mo)

安装与启动

cnpm i -g @nestjs/cli
nest new [项目名称]
npm run start:devs

文件结构

  • main.ts

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    const app = await NestFactory.create(AppModule);
    await app.listen(3000);
    

    入口文件主文件,类似于Vue的main.ts。通过 NestFactory.create(AppModule)创建一个app,就是类似于绑定一个根组件App.vue。

  • app.module.ts

    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    
    @Module({
    imports: [],
    controllers: [AppController],
    providers: [AppService],
    })
    export class AppModule {}
    

    根模块文件,通过@Module装饰器接受一个含有providers、controllers、imports来描述整个模块。
    在module中注入service,可以在controller中不用实例化service就能够使用。

  • app.controller.ts

    import { Controller, Get } from '@nestjs/common';
    import { AppService } from './app.service';
    
    @Controller()
    export class AppController {
    constructor(private readonly appService: AppService) {} //依赖注入不需要实例化  appService 它内部会自己实例化的我们放上去就可以了。你甚至可以指定名称例如
    
    constructor(@Inject('ABC') private readonly appService: AppService) {}
    @Inject('D') private readonly test : string[]
    //你在module里面就要这样写
    // providers: [{
    //     provide: "ABC",
    //     useClass: AppService
    // }]
    // providers: [{
    //     provide: "D",
    //     useValue: ['TD']
    // }]
    @Get()
    getHello(): string {
        return this.appService.getHello();
    }
    }
    

    可以理解为路由。

  • app.service.ts

    import { Injectable } from '@nestjs/common';
    @Injectable()
    export class AppService {
    getHello(): string {
        return 'Hello World!';
    }
    }
    

    具体增删改查。

  • controller.spec
    测试用例文件,我暂时没研究。

常用命令

nest g co user #controller
nest g mo user #module
nest g s user #service
nest g resource user2 #CURD Template

nest g resource user2会生成名为user2的文件夹。

  • user.controller.spec.ts
  • user.controller.ts
  • user.module.ts
  • user.service.spec.ts
  • user.service.ts
  • dto(Data Transfer Object)主要用于验证入参
    • create-user.dto.ts
    • update-user.dto.ts
  • entities
    • user.entity.ts

练手之Session

cnpm i express-session

在main.ts中引入

import * as session from 'express-session'
app.use(session({ secret: "RuntimeError", name: "rt.session", rolling: true, cookie: {maxAge: null } })) //这里的name便是session的name

在user.controller.ts这样写

export class UserController {
  constructor(private readonly userService: UserService) { }
  @Get('code')
  createCaptcha(@Req() req, @Res() res) {
    const captcha = svgCaptcha.create({
      size: 4,//生成几个验证码
      fontSize: 50, //文字大小
      width: 100,  //宽度
      height: 34,  //高度
      background: '#cc9966',  //背景颜色
    })
    req.session.code = captcha.text //存储验证码记录到session
    res.type('image/svg+xml')
    res.send(captcha.data)
  }

  @Post('create')
  createUser(@Req() req, @Body() body) { //body等于前端传的,前端只有sessionID
    if (req.session.code.toLocaleLowerCase() === body?.code?.toLocaleLowerCase()) {
      return {
        message: "验证码正确"
      }
    } else {
      return {
        message: "验证码错误"
      }
    }

  }
}

前端里面这样写

const submit = async () => {
  await fetch("/api/user/create", {
    method: "POST",
    body: JSON.stringify(formLabelAlign),
    headers: {
      "content-type": "application/json",
    },
  })
    .then((res) => res.json())
    .then((res) => {
      console.log(res)
      if (res.message === '验证码正确')
        ElMessage({
          message: "正确",
          type: "success",
        });
      else
        ElMessage({
          message: "错误",
          type: "error",
        });
    });
};

中间件

nest g mi logger

在作路由守护或跨域等方面相当有效

上传下载文件

拦截器

管道