美文网首页
某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