데브코스 39일차 TIL : Vue [Router, 네비게이션 가드, 로그인 구현, BABEL, POSTCSS]

te-ing·2021년 10월 12일
0
post-thumbnail

바닐라 자바스크립트로는 이해하는데 한참 걸린, 어쩌면 아직도 이해하지 못한 Router를 RouterLink, RouterView 만으로 구현할 수 있다는게 사랑스럽다. 물론 바닐라 자바스크립트의 로직들이 숨어있는 것이겠지만, 아직은 그녀석들이 꼴보기 싫으니 보고싶은 것만 보고싶다.

Vue Router

https://next.router.vuejs.org/

npm i vue-router@next로 설치

routes 폴더의 vue파일은 하나의 페이지로 구분되는 내용이 들어감

<RouterLink to="/">Home</RouterLink> 루트경로 지정 <RouterView /> 페이지 보여줌

http://localhost:8080/#/ /#/ Hash Mode를 의미함

<button @click="$router.push('/')">Home</button> 메인페이지 이동버튼

Hash: 도메인/#/ ...

  • 서버의 요청을 추가적으로 전송할 필요가 없이 페이지를 만들어낼 수 있음.
  • 검색엔진 최적화 불리
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from './Home'

export default createRouter({
  history: createWebHashHistory(), // 반환해서 사용해야 함
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
//main.js
import router from '~/routes'
app.use(router)

QueryString: 주소에서 데이터를 사용할 때 쓰는 것

http://localhost:8080/#/?name=태중&age=26&email=tj@abc.com

query: {name: "태중", age: "26", email: "[tj@abc.com](mailto:tj@abc.com)"}

동적 파라미터

{ path: '/documents/:id', component: Docs } id라는 이름으로 파라미터를 받는다.

http://localhost:8080/#/documents/1234 , $route.params.id : 1234

이때 documents/ 로만 접속하면 NotFound가 뜰텐데, 아래처럼 작성하고 Docs.vue에서 <RouterView /> 를 통해 DocsId를 나타내면 좋다.

      path: '/documents', 
      component: Docs,
      children: [ // 배열 리터럴
        {
          path: ':id', // documents는 중복되므로 제거, '/' 사용하지 않음
          component: DocsId
        },
      ]

하지만 위와 같은 코드로 작성한다면 Docs와 DocsId가 같이 출력이 되는데, DocsId만 출력하길 원한다면 아래의 코드처럼 사용하면 된다.

{ path: '/documents', component: Docs, },
{ path: '/documents/:id', component: DocsId },

name

{ path: '/', name: 'home', component: Home } 으로 설정하면

<button @click="$router.push({ name: 'home'})"> 와 같이 { name: 'home' } 으로 경로설정이 가능하다.

이렇게 이름을 설정하면 아래와 같은 사용도 가능하다.

<RouterLink
    :to="{ 
      name: 'docsId',
      params: { id: '7777'},
      query: { name: '태중', age: 26, email: 'TJ@abc.com' }
    }">
    Documents ID
  </RouterLink>

HTML5(History): 도메인/ ...

  • 주소별 서버전송이 필요할 수 있지만, SPA를 이용하면 index.html으로 전송하도록 하면 됨

npm i vue-router@next 설치

import { createRouter, createWebHistory } from 'vue-router'
import Home from './Home' 

export default createRouter({
  history: createWebHistory(), // createWebHashHistory 에서 Hash 지움

// webpack.config.js 에서 publicPath 추가
output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/', // p
    clean: true
  },
devServer:{
    historyApiFallback: true
  }

webpack.config.js에 publicPath: '/'를 추가하고 npm run build 실행

이후 dist폴더의 index.html을 확인해보면 src가 main.js 에서 /main.js의 절대경로로 바뀜

로컬에서 배포시에는 webpack.config.js파일 맨 아래에 devServer:{ historyApiFallback: true } 추가하여 Fallback을 설정해야 하며, 실제로 배포시에는 배포 서버마다 설정방법이 다름

네비게이션 가드

3~8: 네비게이션을 검증해서 다음페이지로 접속을 허용할 것인지, 다른 페이지로 redirection을 할 것인지 결정

3,4,7처럼 컴포넌트 내부에서 Navigation guards를 실행하는 것은 코드추적을 힘들게 하므로 지양하는 것이 좋다.

메타필드

네비게이션 가드 내부에서 어떤 내용을 처리할 수 있는지 지정하는 것

5강 로그인구현방법

  • Home과 About 페이지를 나눠 About 페이지는 guard.js에서 to.meta.requiresAuth와 store.state.user.isLoggedIn를 이용하여로그인 해야만 들어갈 수 있도록 설정
  • user.js에서 redirect를 이용하여 로그인 시 로그인 페이지 이전으로 돌려보내주고, 로그아웃 하였을 때 requiresAuth=true 페이지라면 '/'으로 이동시킴
  • App.vue에서는 v-if="!isLoggedIn"을 이용해 로그인 한 상태면 로그아웃을, 로그아웃 상태면 로그인 버튼을 보여주도록 설정, 로그인 할 때 로컬스토리지에 isLoggedIn을 넣고, created()에서 dispatch('user.initialize')를 이용해 실행할 때 로그인상태인지 확인해서 로그인 권한을 유지시켜줌

Scroll

createRouter에서 scrollBehavior(to, from, savedPosition){} 으로 스크롤 위치 설정가능,

scrollBehavior() { return { top: 0 } } 옵션으로 페이지 이동시 top:0에 위치하도록 설정 가능 ( 기본값은 스크롤 위치 그대로)

scrollBehavior() { 
	return { 
		el: '#main',
		top: -10 } }

el: 을 이용하여 위처럼 엘리먼트를 기준으로 지정하여 위치설정 가능

Promise, setTimeout()을 이용하여 시간차 스크롤도 가능

BABEL

npm i -D @babel/core @babel/cli 설치

script에 "babel": "babel main.js --out-dir dist"으로 main.js로 진입, dist폴더로 반환설정

babel.config.json 파일 생성 후 @babel/plugin-transform-block-scoping 플러그인 등록,

npm i -D @babel/plugin-transform-block-scoping 설치

이후 npm run babel하면 ES5의 block-scoping 으로 변환됨

이처럼 @babel/plugin-transform-arrow-functions 등의 문법을 등록하면 되는데,

npm i -D @babel/preset-env 를 설치하고 babel.config.json에서 { "presets": ["@bable/preset-env"] } 을 입력하면 자동으로 ES6문법을 ES5문법으로 바꿔줄 수 있다.

browserslist

package.json에서 "browserslist" : "> 0.25%(0.25%이상), not dead(살아있는 페이지)" 같이 지원하고자 하는 브라우저의 범위를 설정 가능

transform-runtime

preset-env의 전역등록 전역이 오염되는 이슈를 보완, 실제 코드에서 사용된 부분만 변환

["@babel/plugin-transform-runtime", { "corejs": 3 }] 옵션 설정시 구형브라우저까지 지원가능

babel의 webpack 구성

npm i -D webpack커맨드라인을 위한 webpack-cli, 개발서버를 위한 webpack-dev-server, html을 연결하기 위한 html-webpack-plugin, 자바스크립트를 웹팩으로 번들할 때 중간에 사용할 babel-loader 설치

이후 webpack.config.js 생성 후 vue 설정할 때처럼 webpack.config.js와 package.json 옵션 설정

// webpack.config.js
const HtmlPlugin = require('html-webpack-plugin')
module.exports = {
  entry: './main.js',
  output: {
    publicPath: '/',
    clean: true
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/, // node_modules 파일 제외
        use: 'babel-loader'
      }
    ]
  },
  plugins: [
    new HtmlPlugin ({
      template: './index.html'
    })
  ]
}
// package.json
{
  "name": "vue-babel",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "babel": "babel main.js --out-dir dist",
    "dev": "webpack-dev-server --mode development",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "ie >= 11"
  ],
  "devDependencies": {
    "@babel/cli": "^7.15.7",
    "@babel/core": "^7.15.5",
    "@babel/plugin-transform-runtime": "^7.15.0",
    "@babel/preset-env": "^7.15.6",
    "@babel/runtime-corejs3": "^7.15.4",
    "babel-loader": "^8.2.2",
    "html-webpack-plugin": "^5.3.2",
    "webpack": "^5.56.0",
    "webpack-cli": "^4.8.0",
    "webpack-dev-server": "^4.3.0"
  }
}

POSTCSS

npm i -D webpack커맨드라인을 위한 webpack-cli, 개발서버를 위한 webpack-dev-server, html을 연결하기 위한 html-webpack-plugin설치

rules: [{ test: /\.css$/, use: [ 'style-loader', 'css-loader','postcss-loader' ] }]

github.com/postcss/postcss PostCSS: 후처리도구, CSS 공급업체 접두사도 붙여줌

npm i -D postcss autoprefixer postcss-loader

profile
프론트엔드 개발자

0개의 댓글