[e7] 바닐라 자바스크립트 실습

김고야·2023년 8월 17일
0

JS Study

목록 보기
8/13
post-thumbnail

프로그래머스 스쿨이 제공하는 과제 테스트 예제를 풀어보다가, 로그인 화면 구현을 실습했다. 그리고 작업 폴더 속에서 여러개의 JS 파일을 만들고, 그걸 모듈로 이용해 좀 더 깔끔하게 작업을 할 수 있는 방법을 공부했다.

index.html
main.js
package.json
src/
	main.css
    app.js
    components/
    		login.js

이런 식의 작업폴더 구조로 시작했다. 구현하고자 하는 기능에는 아직 회원가입은 없었기 때문에, 로그인 버튼 클릭 시 이벤트를 발생 시키고, 그 이벤트에 적절한 조건을 갖춘 아이디와 패스워드가 삽입 되었는 지 검토하는 코드를 만들면 되는 터였다. html 파일의 id를 주요 인자로 사용하여 아주 간단한 형태의 js 코드들을 가이드에 따라 작성하며 이해해 보았다.

1. 단정해진 html
js 파일은 script type="module"로 연결, css 파일은 link태그로 연결했다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="icon" href="favicon.ico" type="image/x-icon" />
    <title>간단한 로그인 화면</title>
    <link rel="stylesheet" type="text/css" href="./src/main.css" />
  </head>
  <body>
    <div class="login-container">
      <h2>로그인</h2>
      <input
        id="username"
        class="input-field"
        type="text"
        placeholder="사용자 이름"
      />
      <input
        id="password"
        class="input-field"
        type="password"
        placeholder="비밀번호"
      />
      <button id="loginButton" class="login-button">로그인</button>
    </div>
    <script type="module" src="main.js"></script>
  </body>
</html>

2. main.js
main.js는 html과 연결하여, 다른 모든 기능별 js.파일을 import해 붙여줄 수 있는
물리적 공간을 형성한다. 프로젝트의 유지보수에 무척 좋다는 걸 깨닳았다.

/* 구현하고자 하는 각 기능을 이렇게 분리하여 작성한 것을 모듈이라고 하고,
같은 JS 파일 내부에서 불러내어 사용할 수 있다. 코드의 가독성을 올린다 */
import App from "./src/app.js";

new App(document.querySelector("body"));

3. app.js
this. 는 함수를 호출하는 주체에 따라 다른 값을 가지는 동적인 성격을 가지고 있다.

import Login from "./components/login.js";

// 클래스 App를 선언
class App {
  /* constructor 함수를 선언, 쿼리셀렉터로 id, pw, button의 id를 지정
   JS에서 html에 관여할 수 있게 시동을 걸어주는 메소드*/
  constructor() {
    // this.는 함수를 호출한 주체에 따라 동적으로 다른 값을 가진다
    this.emailInput = document.querySelector("#username");
    this.passwordInput = document.querySelector("#password");
    this.theaterLoginBtn = document.querySelector("#loginButton");
    this.render();
  }
  handleLoginClick = () => {
    new Login(this.emailInput, this.passwordInput);
  };
  // 아래 컴포넌트가 그리는 UI를 생성하고 반환하는 render()
  // 로그인 버튼을 click하면 handleLoginClick 함수를 작동한다
  render() {
    this.theaterLoginBtn.addEventListener("click", this.handleLoginClick);
  }
}
export default App;

4. login.js
login -> app -> main -> html 순서로 각 기능을 구현한 모듈들이 클라이언트로 직접 관여하며 기능을 완성하고 있다. 그동안은 이 모든걸 하나의 js파일에서 작업했었는데, 이렇게 작은 프로젝트에서는 그게 못 할 일은 아니지만, 이런 방식이 가진 장점에 대해 크게 깨닳았다.

// Login 클래스 생성
class Login {
  // 생성자는 html에서 받는 id와 pw를 매개변수로 실행된다
  constructor(emailInput, passwordInput) {
    this.emailInput = emailInput;
    this.passwordInput = passwordInput;
    this.render();
  }
  // 입력값들이 공백으로 인해 에러가 나는 것을 방지하고자, trim()으로 공백을 지워주는 단
  checkRequiredValueIsEnteredInField() {
    return [this.emailInput, this.passwordInput].every(
      (input) => input.value.trim() !== ""
    );
  }
  // id가 요구조건을 충족하는 지 검토하는 함수
  checkEmailFormat() {
    const re = /^[a-zA-Z0-9\.]+@[a-z0-9-_\.]+\.co$/;
    const email = this.emailInput.value;
    return re.test(email.trim());
  }
  // pw가 조건에 부합하는 길이와 요소를 포함하고 있는 지 검토하는 두 함수
  checkPasswordInputLength(minLength, maxLength) {
    const passwordLength = this.passwordInput.value.length;
    return !(passwordLength < minLength || passwordLength > maxLength);
  }
  checkPasswordCombinationValidation() {
    const re = /^(?=.*[a-zA-Z])(?=.*[!@~])(?=.*[0-9])[a-zA-Z0-9!@~]{8,20}$/;
    const password = this.passwordInput.value;
    return re.test(password);
  }
  // render()는 구현된 부분들을 클라이언트에서 볼 수 있게 그려준다
  render() {
    // 유효성 검사는 배열인데, 객체와 함수를 내포하고 있다
    const validations = [
      {
        fn: this.checkRequiredValueIsEnteredInField,
        errMsg: "아이디 혹은 비밀번호가 입력되지 않았습니다.",
      },
    ];
    for (let validation of validations) {
      if (!validation.fn.call(this)) {
        alert(validation.errMsg);
        return;
      }
    }

    alert("로그인 성공!");
    location.reload();
  }
}
export default Login;
profile
Frontend Engineer

2개의 댓글

comment-user-thumbnail
2023년 8월 17일

개발자로서 배울 점이 많은 글이었습니다. 감사합니다.

1개의 답글