회원 가입 폼 - 정보 UX 선택하기

 

데이터와 기능에따라 화면을 변경하는 것으로 render 메소드와 update 메소드를 구분했다. render 메소드는 화면을 변경할 때 해당하는 컨테이너의 모든 내용을 전부 렌더링 하는 반면에 update 메소드는 해당하는 화면의 컨테이너의 기존 기능과 내용은 그대로 두고 새로운 기능이나 내용을 렌더링 한다. 

 

export default class TextField {
  private template = template;
  private container: string;
  private data: Props;  
  private updated: boolean = false;
  private validateRules: ValidateRule[] = [];

  constructor(container: string, data: Props) {
    this.container = container;
    this.data = { ...DefaultProps, ...data };

    if (this.data.require) {
      this.addValidateRule(RequireRule);
    }

    nextTick(this.attachEventHandler);
  }

  private validate = (): ValidateRule | null => {
    const target = this.data.text ? this.data.text.trim() : '';

    const invalidateRules = this.validateRules
      .filter(validateRule => validateRule.rule.test(target) !== validateRule.match);

    return (invalidateRules.length > 0) ? invalidateRules[0] : null;
  }

  private buildData = () => {
    const isInvalid: ValidateRule | null = this.validate();

    if (this.updated) {
      return {
        ...this.data, 
        updated: this.updated,
        valid: !isInvalid,
        validateMessage: !!isInvalid ? isInvalid.message : ''
      }
    } else {
      return {
        ...this.data, 
        updated: this.updated,
        valid: true,
        validateMessage: ''
      }
    }
  }

  private onChange = (e: Event) => {
    ...
  }

  private attachEventHandler = () => {
    ...
  }

  private update = () => {
    const container = document.querySelector(`#field-${this.data.id}`) as HTMLElement;
    const docFrag = document.createElement('div');

    docFrag.innerHTML = this.template(this.buildData());
    container.innerHTML = docFrag.children[0].innerHTML;
  }

  public get name(): string {
    ...
  }

  public get value(): string {
    ...
  }

  public get isValid(): boolean {
	...            
  }

  public addValidateRule = (rule:ValidateRule) => {
    ...
  }

  public render = (append: boolean = false) => {
    ...
}

 

update 메소드를 통해서 화면을 렌더링하는 부분에서 buildData 메소드를 사용하게 된다. 이 메소드는 fields에 저장된 데이터를 가져오는 역할을 하는데 데이터의 유효성을 체크하기 위해 vaildate 메소드를 사용할 것이다. validate 메소드는 저장 되어있는 데이터를 filter 함수를 통해 순회하게된다. rule이 정규식으로 이루어져 있기때문에 데이터의 입력과 매칭이 되는지 안되는지 체크를 할것이다. boolean 값으로 체크를 하게 되면 순회하고나서 하나도 체크되는 값이 없으면 통과가 될것이고 하나라도 체크된다면 해당하는 유효성을 검증하고 메세지를 보내줄 것이다.

 

돌아와서 validate 메소드에서 체크한 값을 buildData 메소드에서 사용하기전에 buildData 메소드는 updated 값을 체크하게 된다. 그 이유는 처음 화면을 로딩했을 때 한번이라도 필드의 값의 변경이 일어났는지 아닌지의 체크를하고 한번 이상일 시에만 밸리데이션 체크값을 보낼 수 있도록 체크를 한다.

 

이렇게 실행을 하고나면 template에 buildData 메소드에서 반환하는 값을 전달한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 정보 UX 선택하기

 

회원 가입 폼에서 해당하는 필드 값들을 입력했을 때, 이벤트 핸들러에서 변경이 되는 부분을 체크하고 해당하는 부분이 맞다면 onChange 메소드를 실행하여 변경된 값을 체크하고 값을 가져오는 부분까지 진행했다.

 

onChange 메소드에는 update 메소드를 실행하는데 update 메소드 이후에 진행에 대해 알아보겠다.

 

export default class TextField {
  private template = template;
  private container: string;
  private data: Props;  
  private updated: boolean = false;
  private validateRules: ValidateRule[] = [];

  constructor(container: string, data: Props) {
    this.container = container;
    this.data = { ...DefaultProps, ...data };

    if (this.data.require) {
      this.addValidateRule(RequireRule);
    }

    nextTick(this.attachEventHandler);
  }

  private validate = (): ValidateRule | null => {
    ...
  }

  private buildData = () => {
    ...
  }

  private onChange = (e: Event) => {
    const { value, id } = e.target as HTMLInputElement;
  
    if (id === this.data.id) {
      this.updated = true;
      this.data.text = value;
      this.update();
    }
  }

  private attachEventHandler = () => {
    ...
  }

  private update = () => {
    const container = document.querySelector(`#field-${this.data.id}`) as HTMLElement;
    const docFrag = document.createElement('div');

    docFrag.innerHTML = this.template(this.buildData());
    container.innerHTML = docFrag.children[0].innerHTML;
  }

  public get name(): string {
    ...
  }

  public get value(): string {
    ...
  }

  public get isValid(): boolean {
    ...
  }

  public addValidateRule = (rule:ValidateRule) => {
    ...
  }

  public render = (append: boolean = false) => {
    ...
}

 

update 메소드를 살펴보면 컨테이너를 받아오고 innerHTML을 통해서 만든 필드를 변경하는데, buildData 메소드를 통해 데이터를 받아온 것을 div 태그로 한번 감싸서 컨테이너에 innerHTML로 변경한다. 이렇게 하는 이유는 이벤트 핸들러 때문인데 가장 최상위 컨테이너를 남겨놓고 하위에 있는 필드값을 변경한다. 그렇게하면 이벤트 핸들러를 건드리지 않아서 값을 변경할 때마다 이벤트 핸들러를 새로 추가하지 않아도 된다. 그러면 여러가지 코드 구성이나 메모리 측면에서 생길 수 있는 문제 등을 보완 할 수 있다. 

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 정보 UX 선택하기

 

예전 화면 방식을 살펴보면 정보를 전부 입력하고 submit 버튼을 눌렀을 때, 입력된 정보들의 밸리데이션을 체크하고 최종적으로 사용자에게 결과를 반환해준다.

 

하지만 해당 방식은 잘 사용하지 않는다. 사용자에게 가능한 즉시 결과를 반환해주고 수정할 수 있도록 하는 추세이다. 또한 한번도 입력하지 않았을 시에는 밸리데이션 체크를 하지않으며 한번 이상 입력을 하고 나왔을 시엔 밸리데이션 체크를 하도록 설계한다.

 

export default class TextField {
  private template = template;
  private container: string;
  private data: Props;  
  private updated: boolean = false;
  private validateRules: ValidateRule[] = [];

  constructor(container: string, data: Props) {
    this.container = container;
    this.data = { ...DefaultProps, ...data };

    if (this.data.require) {
      this.addValidateRule(RequireRule);
    }

    ...
  }

  private validate = (): ValidateRule | null => {
    ...
  }

  private buildData = () => {
	...
  }

  private onChange = (e: Event) => {
    const { value, id } = e.target as HTMLInputElement;
  
    if (id === this.data.id) {
      this.updated = true;
      this.data.text = value;
      this.update();
    }
  }

  private attachEventHandler = () => {
    document.querySelector(this.container)?.addEventListener('change', this.onChange);
  }

  private update = () => {
    ...
  }

  public get name(): string {
    ...
  }

  public get value(): string {
    ...
  }

  public get isValid(): boolean {
    ...
  }

  public addValidateRule = (rule:ValidateRule) => {
    ...
  }

  public render = (append: boolean = false) => {
   ...
  }
}

 

해당하는 필드에 값을 체크하기 위해선 이벤트리스너의 change 값을 체크 해보아야한다. attactchEventHandler 메소드에서 그 작업을 하며, change의 콜백으로 onChange 메소드를 사용한다.

 

onChange 메소드에서는 해당하는 이벤트 타겟의 value와 id 값을 가져와서 App 클래스에 TextField의 인스턴스로 지정 되어있는 id 값과 비교한다. 이유는 필드는 TextField, PasswordField, AddressField 클래스로 나누어져 있고 각 해당하는 필드는 인스턴스로 생성되어 있기 때문이다.

 

돌아와서, onChange 메소드에서 id 값을 체크하고 맞다면 this.updated 변수가 true가 된다. 이 부분이 위에서 설명했던 필드 값에 한번 이상 진입을 했는지 안했는지 체크를 하는 부분이다. 그리고 해당하는 this.data 오브젝트의 text 부분에 입력한 값을 저장하고 update 메소드를 실행한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

회원 가입 폼 웹앱에 사용되는 밸리데이션 구조를 체크하는 로직을 constant.ts 파일에 만들었다. 이제 이러한 각각의 밸리데이션 룰을 어떻게 적용할 것인지에 대해 정해야 한다.

 

하나의 필드에 하나의 밸리데이션만 들어갈 수도 있지만 여러가지의 밸리데이션을 통해 유효성을 체크해야 하는 경우가 있을것이다.

 

export default class App {
  ...
  fields: AnyObject[];

  constructor(container: string, data: AnyObject = {}) {
    ...
    
    this.fields = [];
    this.initialize();
    
    ...
  }

  private initialize = () => {
    const nameField = new TextField('#required-fields', { 
      id: 'name', label: '이름', type: 'text', placeholder: '이름을 입력해주세요', require: true,
    });

    const idField = new TextField('#required-fields', { 
      id: 'id', label: '아이디', type: 'text', placeholder: '아이디를 입력해주세요', require: true,
    });

    const emailField = new TextField('#required-fields', { 
      id: 'email', label: '이메일', type: 'email', placeholder: '이메일을 입력해주세요', require: true,
    });
    
    const passwordField = new PasswordField('#required-fields', { 
      id: 'password', label: '비밀번호', placeholder: '비밀번호를 입력해주세요', 
    });

    const addressField = new AddressField('#optional-fields', {
      id: 'address', label: '배송지 주소',
    });

    idField.addValidateRule(CantContainWhitespace);
    idField.addValidateRule(CantStartNumber);
    idField.addValidateRule(MinimumLengthLimit(3));

    emailField.addValidateRule(CantContainWhitespace);

    this.fields.push(nameField);
    this.fields.push(idField);
    this.fields.push(emailField);
    this.fields.push(passwordField);
    this.fields.push(addressField);
  }

  private validFieldMonitor = () => {
    ...
  }

  private onSubmit = (e: Event) => {
    ...
  }

  public render = () => {
    this.container.innerHTML = this.template(this.data);
    this.fields.forEach(field => {
      field.render(true);
    });

    this.container.addEventListener('submit', this.onSubmit);
  }
}

 

App 클래스에 fields 배열엔 AnyObject 타입의 배열을 받는다. 또한 App 생성자함수에선 처음에 모든 기능을 초기화하는 initialize 메소드를 실행하는데 이 때, 각 필드별로 사용될 인스턴스를 생성하고 해당하는 인스턴스에 addVaildateRule 메소드를 통해 여러가지 밸리데이션을 등록한다. initalize 메소드를 보면 idField에는 세가지의 밸리데이션이 추가되고 emailField에는 한가지의 밸리데이션이 추가된다.

 

처음 생성시 초기화 작업이 되고나서 App 인스턴스의 render 메소드를 통해 해당하는 View 클래스의 인스

턴스에 추가된 render 메소드를 호출해주면 UI 전체가 만들어지는 형태가 될 것이다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

밸리데이션 체크

 

회원 가입 폼을 만들면서 각 필드의 유효성을 체크하는 항목이 필요하다. 최소 몇 글자여야하는지, 대문자인지 소문자인지, 숫자로 시작하는지 등의 유효성 체크를 하는데 있어 if~else 문을 통해 여러가지의 항목들을 체크할 수도 있지만 이러한 코드는 어떻게 기능을 구현을 해놓는다 한들 유지보수를 하거나 또 다른 기능이 추가될 시에 비용이 배로들거나 기능 구현에 어려움이 생길것이다.

 

그렇기 때문에 정규식(RegExp)을 사용한다.

(types/common.ts)

export type ValidateRule = {
  rule: RegExp;
  match: boolean;
  message: string;
}

types 폴더에 common.ts 파일에 있는 정규식에 관한 타입을 정의한 부분이다. ValidateRule은 rule에 정규식을 입력받고 match를 통해 해당 정규식과 문자열의 true/false 체크를 할 것이며, message는 정규식의 결과를 틀리거나 맞았을 때, 그에 대한 사용자에게 전달할 설명을 갖는다.

 

 

(constant.ts)

import { ValidateRule } from "./types";

export const RequireRule: ValidateRule = {
  rule: /.+/,
  match: true,
  message: '필수 입력 항목입니다.',
};

export const CantContainWhitespace: ValidateRule = {
  rule: /\s/,
  match: false,
  message: '공백을 포함할 수 없습니다.',
};

export const CantStartNumber: ValidateRule = {
  rule: /^\d/,
  match: false,
  message: '숫자로 시작하는 아이디는 사용할 수 없습니다.',
}

export const MinimumLengthLimit = (limit: number): ValidateRule => ({
  rule: new RegExp(`(.){${limit}}`),
  match: true,
  message: `최소한 ${limit}글자 이상 이어야 합니다.`,
});

constant.ts 파일엔 ValidateRule의 타입을 기반한 각각의 정규식들을 가지고 있다.

RequireRule ".+" => "."은 \를 제외한 모든 문자를 의미하며 "+"는 1개 이상의 문자가 나올 수 있다는 것을 의미한다.

CantContainWhitespace "\s" => "\s"는 공백을 의미한다. 반대로 "\S"는 반대로 공백을 아닌것을 의미한다.CantStartNumber "^\d" => "^"는 첫번째의 문자를 의미하며 "\d"는 모든 숫자를 의미한다.MinimumLengthLimit "`(.){숫자}`" => ()는 문자열을 하나로 인식하며, "."은 \를 제외한 모든 문자이며 {}안에 있는 숫자는 최소한의 숫자 값을 의미한다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

views 폴더의 text-field.ts 구조

 

text-field는 아마 회원 가입 폼에서 가장 많이 사용하게되는 항목일 것이다. text-field.ts 파일의 구조를 알아보겠다.

 

import { nextTick } from '../utils';
import { ValidateRule } from '../types';
import template from './text-field.template';
import { RequireRule } from '../constant';

type Props = {
  id: string;
  label: string;
  type: 'text' | 'email' | 'number';
  placeholder?: string;
  text?: string;
  require: boolean;
}

const DefaultProps: Props = {
  id: '',
  text: '',
  label: 'label',
  type: 'text',
  placeholder: '',
  require: false,
};

export default class TextField {
  private template = template;
  private container: string;
  private data: Props;  
  private updated: boolean = false;
  private validateRules: ValidateRule[] = [];

  constructor(container: string, data: Props) {
    this.container = container;
    this.data = { ...DefaultProps, ...data };

    if (this.data.require) {
      this.addValidateRule(RequireRule);
    }

    nextTick(this.attachEventHandler);
  }

  private validate = (): ValidateRule | null => {
    ...
  }

  private buildData = () => {
    ...
  }

  private onChange = (e: Event) => {
    ...
  }

  private attachEventHandler = () => {
    ...
  }

  private update = () => {
    ...
  }

  public get name(): string {
    return this.data.id;
  }

  public get value(): string {
    ...
  }

  public get isValid(): boolean {
    ...
  }

  public addValidateRule = (rule:ValidateRule) => {
    ...
  }

  public render = (append: boolean = false) => {
    const container = document.querySelector(this.container) as HTMLElement;

    if (append) {
      const divFragment = document.createElement('div');
      divFragment.innerHTML = this.template(this.buildData());

      container.appendChild(divFragment.children[0]);
    } else {
      container.innerHTML = this.template(this.buildData());
    }
  }
}

 

text-filed.ts에도 많은 메소드들이 있지만 먼저 웹앱의 화면이 변화되는 구조를 먼저 보면, 여기도 app.ts 파일과 마찬가지로 render 함수를 통해서 변경된다.

 

차례대로 살펴보면 data에 사용될 props 타입을 정의했고, DefaultProps 변수에 아무런 데이터가 입력되지 않았을 시에 기본값으로 설정될 프로퍼티들을 정의했다.

 

TextField 클래스를 보면 app.ts와 마찬가지로 template을 사용하고 container를 통해 컨테이너가 될 엘리먼트의 아이디나 클래스 값을 정의한다. Props 타입으로 정의했던 데이터를 정의한 data필드와 update 유무체크하는 updated 변수, 유효성을 체크하는 validateRules 필드를 정의한다.

 

또한 TextField 클래스의 render 메소드에는 append라는 boolean 타입의 파라미터를 받아오는데 app.ts 와는 다르게 회원 가입 폼의 각 필드들은 innerHTML만을 사용하게되면 하나의 필드를 입력하고 다른 필드를 입력했을 시에 다른 필드를 덮어쓰게 된다. append 파라미터는 boolean 타입으로 해당하는 필드가 있을 시에 새로운 div를 생성하여 하단에 추가하는 형태로 기능을 만들것인지 아니면 기존의 필드를 새로 덮어쓰기 하여 생성할 것인지 체크하는 기능을 하게 될것이다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

app.ts의 전체적인 구조

 

import template from './app.template';
import { CantContainWhitespace, CantStartNumber, MinimumLengthLimit } from './constant';
import { AnyObject } from './types';
import { TextField, PasswordField, AddressField } from './views';

export default class App {
  template = template;
  data: AnyObject;
  container: HTMLElement;
  fields: AnyObject[];
  active: boolean = false;

  constructor(container: string, data: AnyObject = {}) {
    this.container = document.querySelector(container) as HTMLElement;
    this.data = data;
    this.fields = [];

    this.initialize();
    
    setInterval(this.validFieldMonitor, 1000/30);
  }

  private initialize = () => {
    const nameField = new TextField('#required-fields', { 
      id: 'name', label: '이름', type: 'text', placeholder: '이름을 입력해주세요', require: true,
    });

    const idField = new TextField('#required-fields', { 
      id: 'id', label: '아이디', type: 'text', placeholder: '아이디를 입력해주세요', require: true,
    });

    const emailField = new TextField('#required-fields', { 
      id: 'email', label: '이메일', type: 'email', placeholder: '이메일을 입력해주세요', require: true,
    });
    
    const passwordField = new PasswordField('#required-fields', { 
      id: 'password', label: '비밀번호', placeholder: '비밀번호를 입력해주세요', 
    });

    const addressField = new AddressField('#optional-fields', {
      id: 'address', label: '배송지 주소',
    });

    idField.addValidateRule(CantContainWhitespace);
    idField.addValidateRule(CantStartNumber);
    idField.addValidateRule(MinimumLengthLimit(3));

    emailField.addValidateRule(CantContainWhitespace);

    this.fields.push(nameField);
    this.fields.push(idField);
    this.fields.push(emailField);
    this.fields.push(passwordField);
    this.fields.push(addressField);
  }

  private validFieldMonitor = () => {
    const btnJoin = this.container.querySelector('#btn-join') as HTMLButtonElement;

    if (this.fields.filter(field => field.isValid).length === this.fields.length) {
      this.active = true;
      btnJoin.classList.remove('bg-gray-300');
      btnJoin.classList.add('bg-green-500');
    } else {
      this.active = false;
      btnJoin.classList.remove('bg-green-500');
      btnJoin.classList.add('bg-gray-300');
    }
  }

  private onSubmit = (e: Event) => {
    e.preventDefault();

    if (!this.active) return;

    const submitData: AnyObject = this.fields
        .map(field => ({ [field.name]: field.value }))
        .reduce((a, b) => ({ ...a, ...b }), {});

    console.log(submitData);
  }

  public render = () => {
    this.container.innerHTML = this.template(this.data);
    this.fields.forEach(field => {
      field.render(true);
    });

    this.container.addEventListener('submit', this.onSubmit);
  }
}

app.ts는 각 views에서 가져온 text, password, address 필드의 변경된 사항이나 밸리데이션 구조 등을 전체적으로 취합해서 화면을 렌더링한다.

 

구조를 보면 기본적으로, 화면의 구조적인 UI를 가지고있는 template(app.template.ts), 각 컴포넌트에 해당하는 데이터를 가진 AnyObject를 반환하는 data와 filelds, 최상위 컨테이너를 지정하는 container, 회원가입 시 궁극적인 유효성 체크를 진행하는 active 필드 등이 있다.

 

또한 메소드 initialize()는 초기 화면을 구동했을 시에 사용하는 필드와 해당하는 필드에 들어가는 데이터 등을 인스턴스로 생성한다. validFiledMonitor()은 화면에 있는 모든 필드의 입력과 밸리데이션을 충족 했을 시에 회원 가입을 진행하는데, 모든 조건이 충족되어있는가를 체크하는 메소드이며 onSubmit()은 vaildFieldMonitor()에서 모든 조건을 충족했을 시 회원 가입을 진행할 수 있다. render()는 위이 모든 기능들의 변경에 따라 보여지는 데이터나 UI 등이 변경된다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

회원 가입 폼 - 밸리데이션 구조 설계

 

회원 가입 폼 웹앱은 index.ts 파일에 app.render() 메소드를 통해 app.ts에 정의 되어있는 기능들의 렌더링이 일어난다는것을 알게 되었다. app.ts 에 웹앱을 이루는 모든 파일들이 정의되어 있기 때문에 폴더 구조를 토대로 사용되는 파일들을 알아볼 것이다.

 

- types 폴더 - address.ts - common.ts - index.ts - user.ts

 

회원 가입 웹앱에 사용되는 타입들을 모아 놓은 폴더이다.

 

(address.ts)

export type Address = {
  zip: string;
  address1: string;
  address2: string | '';
};

export type DaumAddress = {
  address: string;
  autoJibunAddress: string;
  roadAddress: string;
  sigunguCode: string;  
}

회원 가입 폼에 있는 주소 입력창에 대한 타입 정의이다. 회원 가입 폼에 입력 하는 주소 형태의 타입과 웹앱에서 사용되는 주소에 다음 지도 API에서 가져오는 데이터 타입의 구조를 정의 해놓은 파일이다.

 

(common.ts)

export type AnyObject = {
  [key: string]: any;
}

export type ValidateRule = {
  rule: RegExp;
  match: boolean;
  message: string;
}

AnyObject는 웹앱에서 사용되는 object로 사용되는 데이터 타입을 정의했다. 어떤 데이터 타입이 올지 모르게때문에 오브젝트 형태로 받아올 수 있도록 정의했고 ValidateRule은 벨리데이션 구조를 정의하는 타입으로 지정했다.

 

(index.ts)

export * from './common';
export * from './address';
export { default as User }  from './user';

type을 정의한 types 폴더에 각 파일들을 사용하는 파일에서 한번에 import하여 사용하기 편하도록 export를 모아놓은 파일이다.

 

(user.ts)

import { Address } from './address';

type User = {
  name: string;
  id: string;
  email: string;
  password: string;
  address?: Address;
};

export default User;

회원 가입의 User에서 사용되는 타입을 정의 해놓은 파일이다. 이름, 아이디, 이메일, 비밀번호 등을 받고 주소의 경우는 address.ts에서 import 해오며 옵션 형태로 입력을 받거나 안받을 수 있는 형태이다.

 

 

 

 

https://bit.ly/37BpXiC

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

 

#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #김민태의프론트엔드아카데미:제1강JavaScript&TypeScriptEssential

+ Recent posts