美文网首页
某angular项目架构学习

某angular项目架构学习

作者: 南蓝NL | 来源:发表于2018-07-04 10:11 被阅读0次
搭建angular项目
1.安装typescript (在这之前安装好node和淘宝镜像)
cnpm i -g typescript
2.安装angular脚手架
cnpm i -g angular-cli
第二次安装上面两步就不要了
3. ng new+项目名称
4. cd 项目名称
5.cnpm i 安装依赖
6.ng server/npm start
配置sass(本项目中使用sass,每个项目可根据实际情况来定)
1. 安装sass和loader
cnpm i node-sass --save-dev
cnpm i sass-loader --save--dev
2. 配置angular.json
  "styles": [
              "src/styles.scss"
            ],

 "schematics": {
        "@schematics/angular:component": {
          "styleext": "scss"
        }
3.然后在生成component时可以自动生成后缀名为.scss的文件
配置ng-zorro
1. npm i ng-zorro-antd --save
2.引入模块
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { NgModule } from '@angular/core';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd'
import { AppComponent } from './app.component';
import { HeaderComponent } from './share/components/header/header.component';
@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    NgZorroAntdModule.forRoot()
  ],
  providers: [ { provide: NZ_I18N, useValue: zh_CN } ], // 配置ng-zorro-antd国际化
  bootstrap: [AppComponent]
})
export class AppModule { }
3. 配置angular.json
 "styles": [
              "./node_modules/ng-zorro-antd/src/ng-zorro-antd.less",
              "src/styles.scss"
            ],
配置路由
1. 添加AppRoutingModule
ng generate module app-routing --flat -module=app
--flat 把这个文件放进了src/app中,而不是单独的目录中
--module=app 告诉cli把它注册到AppModule的imports数组中
2. 添加路由定义
import { Routes } from '@angular/router';
import { environment } from '../environments/environment';
export const routes: Routes = [
    {
        path: 'login',
        loadChildren: 'src/app/pages/login/login.module#LoginModule'
    }
]
//route.ts这里是将路由定义作为一个文件引入


import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { routes } from '../routes'; //这里引入routes的index.ts文件
import { environment } from '../environments/environment';
@NgModule({
  imports: [RouterModule.forRoot(routes)],//初始化路由器,并让它开始监听浏览器中的地址变化
  exports: [RouterModule]
})
export class AppRoutingModule { }
//app-routing.module.ts

3. 在app.component.html添加路由出口
<div class="main">
    <router-outlet></router-outlet>
</div>
4. 每个组件也要配置路由
 ng g m 组件名称 --routing
 ng g c 组件名称
比如这里的login.module组件需要在login-routing.module.ts配置路由
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login.component';
const routes: Routes = [
   {
     path: '',
     component: LoginComponent
   }
];
@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class LoginRoutingModule { }
// login-routing.module.ts
配置服务
1. 创建一个服务
ng g serve 服务名称
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Res } from '../interfaces/res.interface';

@Injectable({
  providedIn: 'root'
})
export class LoginService {
  constructor(private http: HttpClient) { }
  // 登录
  public login(user): Observable<Res> {
    return this.http.post<Res>('/api/user/login', user)
  }
}
// login.service.ts

export interface Res<T = any> {
  data: T
  status: number
  msg: string
}
//res.interface
2. 引入服务(在要使用服务的组件上)
比如import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginRoutingModule } from './login-routing.module';
import { LoginComponent } from './login.component';
import { LoginService } from '../../share/serve/login.service'
@NgModule({
  imports: [
    CommonModule,
    LoginRoutingModule,
    ReactiveFormsModule
  ],
  declarations: [
    LoginComponent,
  ],
  providers:[LoginService]  //这里必须要写
})
export class LoginModule { }
//login.module.ts
3. 订阅服务
import { Component, OnInit } from '@angular/core';
import { FormBuilder,FormGroup } from '@angular/forms';
import { LoginService } from '../../share/serve/login.service';
import { NzMessageService } from 'ng-zorro-antd';
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
  constructor(private fb: FormBuilder,
      private loginServer: LoginService,
      private msg: NzMessageService
    ) { }
    public code: string  = '';
    public loginForm: FormGroup
  ngOnInit() {
    this.loginForm = this.fb.group({
      username: [''],
      password: [''],
      authCode: ['']
    })
    // 得到验证码
    this.loginServer.getAuthCode().subscribe(
      (res) =>{
        this.code = 'data:image/png;base64,' + res
      }
    )
  }
// 订阅服务的具体步骤
  public login(){
    this.loginServer.login(this.loginForm.value).subscribe(
      (res) =>{
        const { data } = res
        localStorage.setItem('token', data.token)
        this.msg.info(res.msg);
      }
    )
  }
}
// login.component.ts,这里简略地阐述下登录的过程.首先发起获取验证码的请求,将验证码渲染在页面上,然后提交登录信息,带上token发起login的请求
4. 配置代理
{
  "/api": {
    "target": "https://www.sceo360.com",
    "changeOrigin": true,
    "pathRewrite": {
      "^/api": "/api"
    }
  }
}
// proxy.conf.json
{
    "name": "http",
    "version": "0.0.0",
    "scripts": {
        "ng": "ng",
        "dev": "ng serve --proxy-config=proxy.conf.json",
        "start": "ng serve",
        "build": "ng build",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e"
    }
// package.json
登录拦截器
import { Injectable } from '@angular/core'
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpResponse,
} from '@angular/common/http'
import * as qs from 'qs'

import { Observable } from 'rxjs'
// import { AuthServiceService } from '../serves/auth-service/auth-service.service';
import { tap } from 'rxjs/operators'; //捕获请求的状态
import { Router } from '@angular/router';
import { environment } from '../environments/environment';
// import { SimpleReuseStrategy } from '../share/simple-reuse-strategy';

@Injectable()
export class SetTokenHeaderInterceptor implements HttpInterceptor {
  constructor( private router: Router) {}
  // intercept方法会把请求转换成一个最终返回HTTP响应的observeable.
  // next对象表示拦截器链表中的下一个拦截器
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
    const { body, method, headers } = req
    const customerHeaders = {
      'Content-Type': headers.get('Content-Type') || 'application/x-www-form-urlencoded'
    }
    // 在克隆请求的同时设置新请求头
    const reqWithToken = req.clone({
      setHeaders: customerHeaders,
      body: method.toLocaleLowerCase() === 'post' || !headers.get('Content-Type') ? qs.stringify(body) : body
    })

  // 以便这个请求能走到下一个拦截器,并最终传给后端处理器
    return next.handle(reqWithToken)
      .pipe(
        tap(
          (event) => {
            if (event instanceof HttpResponse) {
             // console.log(event.body)
              const { status } = event.body
              switch(status) {
                case 400:
                  environment.production && (location.href = '/login') 
                  // 清空所有缓存路由
                  // SimpleReuseStrategy.handlers = {}
                  break;
              }
            }
          }
        )
      )
  }
}
// set-token-header-interceptor.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http'
// 设置token请求头
import { SetTokenHeaderInterceptor } from './set-token-header-interceptor'

export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: SetTokenHeaderInterceptor, multi: true }
]
// index.ts
然后再根组件中引入

相关文章

网友评论

      本文标题:某angular项目架构学习

      本文链接:https://www.haomeiwen.com/subject/gcyduftx.html