工程训练:生意专家:03 注册的实现

0. 项目目录

  1. 欢迎页的实现
  2. 程序第一次运行实现
    == 3. 注册的实现 ==
  3. 登陆的实现
  4. 首页的实现
  5. 店铺设置的实现
  6. 商品分类浏览的实现
  7. 编辑商品分类的实现
  8. 新增商品的实现
  9. 商品管理的实现

1. 任务

1.1 任务介绍

实现用户的注册功能。

1.2 任务要求

用户场景: 用户注册之后才能有权限使用软件的功能。用户在欢迎页点击“注册”按钮进入注册页,或者在登录页点击“注册”按钮进入注册页。
输出/后置条件: 注册成功后,由于没有搭建服务器端,因此注册的数据保存在浏览器的本地存储中。页面跳转到首页。
**在欢迎页中点击“跳转”按钮的处理:**通过Angular的事件绑定,点击“跳过”按钮时页面跳转到首页。

2. 思路

1. 把经常用的功能放在share模块中,创建share模块
2. 路由上打通:
---- ①passport与注册signup路由打通;
---- ②根路由与passport打通
3. 模块声明好,让相互之间知道:
---- ① passport与注册signup模块打通;
---- ②根模块与passport打通

4. 注册页面的配置

3. 使用Module管理代码

在小型的项目中可以参考欢迎页的做法直接在pages文件夹中创建页面,但是功能多起来就不好管理。你可以直接创建文件夹分门别类管理好每个页面,也可以使用模块管理页面。例如可以把注册、登录、修改密码等页面都归到passport模块中管理。如果你觉得使用模块的方式组织项目结构比较复杂,你也可以不创建passport模块,只创建passport文件夹。在简单的项目中你可以这么处理,但在实际的项目中建议使用模块。
发现前面一个小问题
我没有pages文件夹 于是我建了个文件夹 然后把welcome移到里面了 然后做了相应的改动(主要是相对地址)
在这里插入图片描述

4 创建passportModule

4.1 创建模块passport,同时添加passport路由

目的就是用passport模块来管理注册 登录等一系列模块
在小型的项目中可以参考欢迎页的做法直接在pages文件夹中创建模块passport,同时添加passport路由:

ionic g module passport --routing

在这里插入图片描述

4.2 创建注册页面和登录页面

在passport下
在这里插入图片描述
在这里插入图片描述

4.3 删去signup文件夹下signup.routing.ts和signup.module.ts这两个文件

同理login文件夹
不想让每个页面都带一个路由和模块
在这里插入图片描述

4.4 在passport的路由文件夹添加路由信息

完成思路.2.①

const routes: Routes = [
 { path: 'signup',
  component: SignupPage
 },
 {
  path: 'login',
  component: LoginPage
}

];

这是一个数组,放的是对象,也是一个route,每个路由有个path和组件名称
在这里插入图片描述

4.5 在app的路由文件夹添加passport路由信息

完成思路.2.②

{
    path: 'passport',
    loadChildren: () => import('../app/pages/passport/passport.module').then( m => m.PassportModule),
  }

在这里插入图片描述

4.6 模块声明

完成思路.3.①
要让passport知道有两个对象login和signup
一般组件 页面都是在这声明
在这里插入图片描述

5 使用share模块

完成思路.1:

1. 第三方模块的导入导出
2. 谁用到这些模块第三方,都要声明share模块

共享模块,指当你需要针对整个业务模块都需要使用一些第三方模块,自定义组件,自定义指令,都应该存在这里。

5.1 导入CommonModule,FormsModule,IonicModule等第三方模块

在这里插入图片描述

5.2 修改exports属性,导出其他模块都需要的模块。

为了别人能用
在这里插入图片描述

share模块代码如下:

import { LocalStorageService } from './local-storage.service';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';



@NgModule({
  declarations: [],
  providers: [
    LocalStorageService
  ], // 服务提供者,不写也没问题
  imports: [
    CommonModule,
    FormsModule,
    IonicModule
  ],
  exports: [
    CommonModule,
    FormsModule,
    IonicModule
  ]
})
export class SharedModule { }

5.3 在PassportModule中导入SharedModule

要用share模块中的第三方就要声明share模块:在这里passport想用到share模块里的模块,就应该让oasport知道由share,所以声明

在这里插入图片描述

5.4 在WelcomeModule中导入SharedModule

我之前有导入过

6 跳转到注册页面

6.1 在欢迎页中点击注册按钮进入注册页

方法一:
为“注册”按钮添加href属性。
src\app\pages\welcome\welcome.page.html

<!-- 为ion-button元素添加href属性 -->
<ion-button color="primary" fill="outline" expand="block" href="/passport/signup">注册</ion-button>

方法二:

<!-- 为ion-button元素添加routerLink属性 -->
<ion-button color="primary" fill="outline" expand="block" routerLink="/passport/signup">注册</ion-button>

在这里插入图片描述

6.2 在欢迎页中点击跳过按钮进入注册页

1. 添加跳过事件
2.跳过事件与点击事件绑定

跳转事件标准

6.2.1 在WelcomePage组件类中添加onSkip方法。

参考之前的任务,使用Router实现从欢迎页导航到注册页。目前还没实现已登录状态下的跳过处理,等到登录任务中再完善逻辑。
在这里插入图片描述

6.2.2 为“跳过”按钮添加click事件绑定

使用 Angular 事件绑定语法把click事件绑定到事件处理器。
src\app\pages\welcome\welcome.page.html

<ion-header class="ion-no-border">
  <ion-toolbar>
   <ion-buttons slot="end" [hidden] = "!showSkip" (click)="onClick()">  
      <ion-button >  // (click)="onClick() 点击执行onClick()
        跳过
      </ion-button>
  </ion-buttons>
  </ion-toolbar>
</ion-header>

在这里插入图片描述

7 实现注册界面

7.1 样式scss

src\app\pages\passport\signup\signup.page.scss
存放样式
①通过样式表设置图片宽度。

界面的顶部放一张图片居中,宽度33%。

.logo {
  width: 33%;
}

② 图片居中
使用类选择器ion-text-center,在旧版Ionic中使用的是属性选择器text-center。后面的任务中喷到类似的情况统一改成class=“ion-text-center”。
src\app\pages\passport\signup\signup.page.html

<div class="ion-text-center">
  <img class="logo" src="assets/img/logo.png" alt="">
</div>

在这里插入图片描述
在这里插入图片描述
③ 居中和水平线
src\app\pages\passport\signup\signup.page.scss

/* 其他省略 */
hr {
  height: 1.5px;
  border: none;
}
.full-width {
  width: 100%;
}

实现添加水平线:
src\app\pages\passport\signup\signup.page.html

<!-- 其他代码省略 -->
<ion-col class="ion-align-self-center">
  <hr>
</ion-col>
<!-- 其他代码省略 -->

7.2 布局

① 放4张图片表示4个步骤。

使用Grid布局,1行7列,第2、4、6列中的内容垂直居中并添加一条水平线。
为注册页添加样式。
src\app\pages\passport\signup\signup.page.scss

/* 其他省略 */
hr {
  height: 1.5px;
  border: none;
}
.full-width {
  width: 100%;
}

图片之间添加水平线。
src\app\pages\passport\signup\signup.page.html

<!-- 其他代码省略 -->
<ion-col class="ion-align-self-center">
  <hr>
</ion-col>
<!-- 其他代码省略 -->


② 放4张图片表示4个步骤
使用Grid布局,1行7列,第2、4、6列中的内容垂直居中并添加一条水平线。
为注册页添加样式。
src\app\pages\passport\signup\signup.page.scss

/* 其他省略 */
hr {
  height: 1.5px;
  border: none;
}
.full-width {
  width: 100%;
}

图片之间添加水平线。
src\app\pages\passport\signup\signup.page.html

<!-- 其他代码省略 -->
<ion-col class="ion-align-self-center">
  <hr>
</ion-col>
<!-- 其他代码省略 -->

③ 使用Slides
包含4个slide子元素,每个slide对应一个form标签,元素不要加pager属性。参考之前的任务自行完成。

<!-- 其他代码省略 -->
<ion-slide>
  <form>
    <ion-list>
      <ion-item>
      </ion-item>
      <!-- 根据需求添加若干ion-item -->
    </ion-list>
  </form>
</ion-slide>
<!-- 其他代码省略 -->

7.3 使用Slides,通过索引判断注册到那一步了,同时亮不同的标

部分代码:

  <ion-grid class="fixed">
    <ion-row>
      <ion-col class="ion-align-self-center">
        <img src="assets/img/registered_one.png" alt="" *ngIf="slideIndex!==0">
        <img src="assets/img/registered_one_one.png" alt="" *ngIf="slideIndex===0">
      </ion-col>
      <hr/>
      <ion-col class="ion-align-self-center">
        <img src="assets/img/registered_two.png" alt="" *ngIf="slideIndex!==1">
        <img src="assets/img/registered_two_two.png" alt="" *ngIf="slideIndex===1">
      </ion-col>
      <hr/>
      <ion-col class="ion-align-self-center">
        <img src="assets/img/registered_three.png" alt="" *ngIf="slideIndex!==2">
        <img src="assets/img/registered_three_three.png" alt="" *ngIf="slideIndex===2">
      </ion-col>
      <hr/>
      <ion-col class="ion-align-self-center">
        <img src="assets/img/register_four.png" alt="" *ngIf="slideIndex!==3">
        <img src="assets/img/register_four_four.png" alt="" *ngIf="slideIndex===3">
      </ion-col>
    </ion-row>
  </ion-grid>

讲解:

7.3.1 通过索引来判断注册进行到哪一步

每个步骤分别对应两张图片,某一种状态下显示其中一张,另外一张隐藏。第一个小标为例
src\app\pages\passport\signup\signup.page.html

      <ion-col class="ion-align-self-center">
        <img src="assets/img/registered_one.png" alt="" *ngIf="slideIndex!==0">
        <img src="assets/img/registered_one_one.png" alt="" *ngIf="slideIndex===0">
      </ion-col>

当*ngIf后面的表达式的结果为true,ngIf会把img添加到DOM中,否则ngIf会从DOM中移除img。

  1. 那么如果slideIndex!==0,那么显示assets/img/registered_one.png
  2. 这张照片;如果slideIndex===0,显示assets/img/registered_one_one.png
7.3.2 通过代码切换4个slide

① 声明变量signupSlides 滑动时同时发生onSlideWillChange()

<ion-slides #signupSlides  (ionSlideWillChange)="onSlideWillChange($event)">

② @ViewChild定义模板引用变量

@ViewChild饰器用于获取模板视图中的元素或直接调用其组件中的方法

在组件类中通过@ViewChild声明对子组件元素的实例引用,意思是通过注入的方式将子组件注入到@ViewChild容器中,你可以想象成依赖注入的方式注入,只不过@ViewChild不能在构造器constructor中注入,因为@ViewChild会在ngAfterViewInit()回调函数之前执行。
说人话就是我理解是感知鼠标
src\app\pages\passport\signup\signup.ts文件

export class SignupPage implements OnInit {
  @ViewChild('signupSlides', { static: true }) signupSlides: IonSlides;
。。。
}
//字符串'signupSlides'和模板中的#signupSlides引用变量的名称一致

export class SignupPage implements OnInit{}
signup初始化的东西,里面有页面表现出来的功能 都在这里搞

③ 定义事件onSlideWillChange()发生什么
触发slideIndex变化
export class SignupPage implements OnInit{}中

  onSlideWillChange(event) {
    this.signupSlides.getActiveIndex().then((index) => {
      this.slideIndex = index;
    });


④ 设置slideIndex初始值
export class SignupPage implements OnInit{}中

  slideIndex = 0;
7.3.2 把退后\前进实现

① 封装功能
同样位置:export class SignupPage implements OnInit{}

ngOnInit() {
    this.signupSlides.lockSwipes(true); // 如果时ture那么就锁定 滑动不了页面
  }
  onNext() {
    this.signupSlides.lockSwipes(false); // 没有所页面
    this.signupSlides.slideNext(); // 当发生滑倒下一页时
    this.slideIndex++; // slideIndex+1
    this.signupSlides.lockSwipes(true); // 就划不动了
  } 
  onPrevious() {
    this.signupSlides.lockSwipes(false);
    this.signupSlides.slidePrev();
    this.slideIndex--;
    this.signupSlides.lockSwipes(true);
  }


先解锁,滑动,参数索引改变,再锁定

② 和按键产生关系实现功能
在“上一步”按钮上绑定click事件,调用onPrevious()。在“下一步”按钮上绑定click事件,调用onNext()。这里onNext没找到在哪用
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在组件类中通过@ViewChild声明对子组件元素的实例引用,意思是通过注入的方式将子组件注入到@ViewChild容器中,你可以想象成依赖注入的方式注入,只不过@ViewChild不能在构造器constructor中注入,因为@ViewChild会在ngAfterViewInit()回调函数之前执行。
src\app\pages\passport\signup\signup.ts文件

创建sugnup,ts
在这里插入图片描述
视图模型的名称与页面的名称一致,也可以在名称的后面加VO(View Object)这个后缀。
src\app\pages\passport\signup\signup.ts在这里插入图片描述

在组件类中通过@ViewChild声明对子组件元素的实例引用,意思是通过注入的方式将子组件注入到@ViewChild容器中,你可以想象成依赖注入的方式注入,只不过@ViewChild不能在构造器constructor中注入,因为@ViewChild会在ngAfterViewInit()回调函数之前执行。
src\app\pages\passport\signup\signup.ts文件

@ViewChild('signupSlides', {static: false}) signupSlides: IonSlides;
//字符串'signupSlides'和模板中的#signupSlides引用变量的名称一致
ngOnInit() {
  this.signupSlides.lockSwipeNext(true);
}
onNext(){
  this.signupSlides.slideNext();
}
onPrevious() {
  this.signupSlides.slidePrev()
}

然后在SignupPage组件类中添加signup属性。并初始化
src\app\pages\passport\signup\signup.page.ts在这里插入图片描述
在这里插入图片描述

事件绑定
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
做下面有问题提示的

          </ion-item >
          <ion-item *ngIf="phone.touched && phone.invalid">
            <ion-text class="ion-text-left" color="danger" *ngIf="phone.errors?.required">
              请输入手机号码
            </ion-text>

            <ion-text class="ion-text-left" color="danger" *ngIf="phone.errors?.pattern">
              您输入的手机号格式不正确
            </ion-text>        
          </ion-item>

在这里插入图片描述
提交保单
添加保单变量 是个angular表单,加上个绑定
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述短信验证
验证码功能基本上用于passport模块,注册或者忘记密码时会使用到。可以在passport文件夹下创建shared文件夹,或者直接在passport文件夹中创建。如果验证码服务在其他模块中也有用到,可以在ShareModule中创建。参考之前的任务创建验证码服务。
src\app\passport\authentication-code.service.ts

@Injectable({
  providedIn: 'root'
})
export class AuthenticationCodeService {
  // 用于保存验证码
  private code: string;
  // 存放验证码的过期时间
  private deadline: number;
  constructor() {
    this.code = '';
  }
  // 生成指定长度的随机数字
  createCode(count: number): string{
    this.code = '';
    // 10分钟内有效
    this.deadline = Date.now() + 60 * 10 * 1000;
    for (let i = 0; i < count; i++) {
      // 请补上相关的代码
    }
    return this.code;
  }
  // 验证用户输入的短信验证码是否一致,是否过期
  validate(value: string): boolean{
    const now = Date.now();
    return value === this.code && now < this.deadline;
  }
}

创建服务AuthenticationCode

在这里插入图片描述

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页