💻 Frontend

Vue Lifecycle 리서치 및 login 기능 구현

date
Jan 3, 2023
slug
vue-lifecycle-login
author
status
Public
tags
Vue.js
Web
Network
summary
Vue Lifecycle 리서치 및 login 기능 구현
type
Post
thumbnail
스크린샷 2022-12-29 오후 4.45.09.png
category
💻 Frontend
updatedAt
Apr 12, 2023 04:25 PM
 
[목차]
 

Chapter 1. Vue Router

Vue Router is the official router for Vue.js
Vue Router는 Vue에 최적화되고, 여러 기능을 제공하는 공식 Router이다. (페이지 이동을 관리해주는 것이다)
경로에 따른 페이지 관리
// path와 component 설정
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]
// 링크 태그로 이동
<router-link to="/router"></router-link>

// push 메서드를 이용한 이동
router.push({path:'home'})

1-1) Vue Router Option

vue router는 path값과 component를 설정하며, 다양한 옵션 설정이 가능하다.
Name
특정 라우터에 Name을 설정해서 해당 Name을 통한 호출이 가능함
// name 설정 
	{
    path: '/user/:username',
    name: 'user',
    component: User
  }

// Name을 통한 라우터 호출
<router-link :to="{ name: 'user', params: { username: 'erina' }}">
  User
</router-link>

router.push({ name: 'user', params: { username: 'erina' } })
Children
path 값에 따른 children으로 여러 개의 자식 컴포넌트 설정도 가능함
//router/index.js
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        path: 'profile',
        component: UserProfile,
      },
      {
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

// 부모 컴포넌트에서 router-view 추가
const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `,
}
Redirect, Alias
redirect 설정을 통해 특정 Path로 redirect가 가능하고, redirect path에 컴포넌트도 등록이 가능하다
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
		{ path: '/a', redirect: { name: 'foo' }}
		{ path: '/a', redirect: to => {
      // 함수는 인수로 대상 라우트를 받습니다.
      // 여기서 path/location 반환합니다.
    }}
  ]
})
const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

1-2) Vue Router Data

router로 데이터를 전달할 수 있다. 실제 router 객체가 들고 있는 정보들은 아래와 같이 다양하다.
notion image
Props
props를 데이터로 설정해주면, matched 속성에서 값으로 확인할 수 있음.
const routes = [
  {
    path: '/promotion/from-newsletter',
    component: Promotion,
    props: { sample: "hi" }
  }
]
notion image
Query
Query는 router-link로 설정했을 경우, url에 query 방식으로 붙어서 값이 설정됨
<router-link
			:to="{ name: 'password', query: { loginState: loginState } }"
			className="link_profile"
			> 비밀번호 변경(query)
</router-link>
Params
<router-link
			:to="{
				name: 'image',
				params: { example: 'hello' },
			}"
			className="link_profile"
			>프로필 이미지 변경(params)</router-link
		>
// router 설정
path: "/router/image/:example",
name: "image",
component: ProfileImage,
props: true,

// 컴포넌트에서 router 불러오기
<div>{{ this.$route.params.loginState }}</div>

// props 설정 시, 변수로 불러오는 것도 가능
<div>이미지 변경 컴포넌트 {{ loginState }}</div>
export default {
	props: ["loginState"],
};
 
 
주소를 묻고 싶을 때는 URL(location)
디테일한 것을 묻고 싶을 때는 URI(identify)
 
원래 param은 path param과 query param으로 구분된다.
즉 둘 다 원래는 param이라는 것.
 
param
-route
-query
-form

Chapter 2. LifeCycle

2-1) LifeCycle 기본

LifeCycle이란 컴포넌트의 생성부터 소멸까지의 단계를 말한다.
vue는 컴포넌트의 생성주기를 4가지 단계로 나눈다
  • Create : Data를 모두 받아온 상태
  • Mount : DOM이 부착된 상태
  • Update : DOM이 변경되었을 때
  • Unmount : 해당 컴포넌트가 해체될 때

2-2) Vue-Component LifeCycle Methods

vue는 라이프사이클에 따라서 특정 작업이 가능하게 methods로 만들어놨다.
4가지단계에 before 단계가 추가되어 총 8단계의 메서드를 지원함.
세부내용
notion image
notion image
 
  • setup
    • composition API. 아무것도 불러오지 않은 상태에서 called
  • create
    • beforeCreate
      • props는 받고, data(), computed는 만들어지기 전에 called 됨
      • 실제로 data를 콘솔에 찍어보면 undefined가 찍힘.
    • created
      • created는 모든 data를 불러온 상태
  • mount (불러온 데이터를 DOM에 반영할 때)
    • notion image
    • beforeMount
      • DOM을 불러오기 직전에 호출 즉, Virtual DOM을 만든 상태
      • beforeMount 이후에 자식 컴포넌트가 있다면, 해당 컴포넌트를 먼저 mount함
    • mounted
      • 자식 컴포넌트를 모두 Mount하고, DOM을 모두 불러온 상태
  • update (DOM이 변경되었을 때)
    • notion image
    • beforeUpdate
      • data는 바뀌고 dom에 반영되지 않은 상태
      • beforeUpdate 하기 전에
    • updated
      • data는 바뀌고 dom에 반영된 상태
  • unmount (컴포넌트가 없어질 때)
    • notion image
    • beforeUnmount
      • unmount 되기 직전에 실행
    • unmounted
      • unmount 되고나서 실행
 

2-3) Vue-Router LifeCycle Methods (Navigation Guard)

vue-router도 특정 주기에 따라 제어할 수 있는 네비게이션 가드가 있다.
사용하는 방법에 따라 navigation guard, data fetching의 역할로 사용할 수 있다.
 
모든 메서드는 to, from, next라는 인자를 받을 수 있다.
to : 이동하기 전의 라우터 정보
from : 이동하고 난 후의 라우터 정보
next : 메서드의 작업이 끝난 후 진행 (이전 라우트로 돌려보내거나, 별도 페이지로 이동 설정 가능)
세부내용
  • 생성순서에 따른 router LifeCycle
notion image
 
Global Router 설정
  • beforeEach : 기존 컴포넌트가 제거된 후 새로운 네비게이션이 시작될 때 호출
  • beforeResolve : 네비게이션 작업을 완료하기 전에 호출되는 훅
  • afterEach : 네비게이션 작업이 완료된 후 호출되는 메서드
 
개별 Router 설정
  • beforeEnter : 개별 router 진입 전 기능 수행
 
컴포넌트에 적용하는 메서드
  • beforeRouteLeave : 기존 컴포넌트 제거전에 이 훅을 호출
  • beforeRouteEnter : 새로운 컴포넌트를 만들기 전에 호출되는 훅
  • beforeRouteUpdate : 컴포넌트 재사용 시 발생하는 훅.
    • ex) board/page/1 → board/page/2
notion image
 

Chapter 3. 로그인 구현

notion image
3-1) 로그인 폼 만들기
  • ID,PW 입력 Input 만들기(data 연동)
  • 로그인 버튼 만들기 (각각 4글자 이상 입력 시 활성화)
  • 엔터키 입력 혹은 로그인 버튼 클릭시 데이터 전송
  • 로그인시 입력창 사라지고, username님 환영합니다 문구생성 및 로그아웃 버튼
3-2) 라우터 로그인 옵션
3-3) 라우터 로그인 필수
로컬스토리지
beforeEnter로 특정 컴포넌트에 로컬스토리지 값으로 로그인 여부 판단
  • URL에 정보를 담지 않아도 된다.
  • 다만webStorage에서 정보를 꺼낼 때 에러상황에 대한 핸들링을 해줘야 함.
path: "/router/profile",
name: "profile",
component: ProfileComponent,
beforeEnter: () => {
		const getToken = JSON.parse(localStorage.getItem("loginState"));
		if (getToken != null) {
			return;
		} else {
			alert("로그인해주세요");
			return "./router";
		}
	},
created() {
		let getToken;
		try {
			localStorage.getItem("loginState");
			getToken = JSON.parse(localStorage.getItem("loginState"));
			this.username = getToken.username;
			this.password = getToken.password;
			this.loginState = getToken.state;
		} catch (error) {
			// console.error("Error", error);
			this.loginState = false;
			this.username = "";
			this.password = "";
			localStorage.removeItem("loginState");
		}
	},
Query
{
		path: "/router/password",
		name: "password",
		component: PasswordChange,
		beforeEnter: (to) => {
			console.log("to", to);
			if (to.query.loginState === "true") {
				return;
			} else {
				alert("로그인이 필요합니다");
				return false;
			}
		},
	},
notion image
 
Params
path: "/router/image/:loginState",
name: "image",
component: ProfileImage,
props: true,
beforeEnter: (to) => {
		if (to.params.loginState === "true") {
			return;
		} else {
			alert("로그인이 필요합니다");
			return false;
		}
	},
notion image