팁
NotePad++의 plug-in(compare)을 사용하면 쉽게 두 파일의 비교가 가능하다.
메뉴의 플러그인 -> 플러그인 관리 -> 찾기에 Compare 검색 후 선택하고 설치 -> 재시작하시겠습니까? 승낙
위처럼 비교하여 다른 부분을 찾아준다.
DB - 백엔드 - 프론트엔드(내가 만든 파일) 연동하기
user.js
// ...
actions: {
// action은 비동기적 사용이 가능하다. (action에서 mutation을 호출하는 방법을 권장함)
// user 리스트
actUserList(context, payload) {
/* RestAPI 호출 */
api
.get('/serverApi/users')
.then(response => {
const userList = response && response.data
context.commit('setUserList', userList)
})
.catch(error => {
// 에러인 경우 처리
console.error('UserList.error', error)
context.commit('setUserList', [])
})
},
// 등록
actUserInsert(context, payload) {
// 상태(결과)값 초기화
context.commit('setInsertedResult', null)
/* RestAPI 호출 */
api
.post('/serverApi/users', payload)
.then(response => {
const insertedResult = response && response.data && response.data.id
context.commit('setInsertedResult', insertedResult)
})
.catch(error => {
// 에러인 경우 처리
console.error('UserInsert.error', error)
context.commit('setInsertedResult', -1)
})
},
// 수정
actUserUpdate(context, payload) {
// 상태값 초기화
context.commit('setUpdatedResult', null)
/* RestAPI 호출 */
api
.put(`/serverApi/users/${payload.id}`, payload)
.then(response => {
const updatedResult = response && response.data && response.data.length > 0 && response.data[0]
context.commit('setUpdatedResult', updatedResult)
})
.catch(error => {
// 에러인 경우 처리
console.error('UserUpdate.error', error)
context.commit('setUpdatedResult', -1)
})
},
// 삭제
actUserDelete(context, payload) {
// 상태값 초기화
context.commit('setDeletedResult', null)
/* RestAPI 호출 */
api
.delete(`/serverApi/users/${payload}`)
.then(response => {
const deletedResult = response && response.data
context.commit('setDeletedResult', deletedResult)
})
.catch(error => {
// 에러인 경우 처리
console.error('UserDelete.error', error)
context.commit('setDeletedResult', -1)
})
},
// ...
// 사용자 정보 조회
actUserInfo(context, payload) {
/* RestAPI 호출 */
api
.get(`/serverApi/users/${payload}`)
.then(response => {
const user = response && response.data
context.commit('setUser', user)
})
.catch(error => {
// 에러인 경우 처리
console.error('UserInfo.error', error)
context.commit('setUser', -1)
})
}
}
}
axios github
method(동사)
get : 조회
post : 등록
put : 수정
delete : 삭제
RestFull API(방향성) --> url은 명사(목적에 해당), method는 동사
=> 무엇을(url) 어떻게(method)
예시 GET /users/delete (x)
DELETE /users (o)
GET /users => 전체 리스트 []
GET /users'1 => id=1인 단 한명{}
프록시를 안쓰면 cors에서 막힘
vue.config.js
const { VUE_APP_SERVER } = process.env
module.exports = {
devServer: {
proxy: {
'/serverApi': {
target: VUE_APP_SERVER,
changeOrigin: true,
pathRewrite: {
'^/serverApi': ''
}
}
}
}
}
이런 식으로 proxy 설정을 해줘야 한다. 결과는 개발자모드의 network 탭에서 확인 가능하다.
Postman
POST 하는 법
RestFull URl
url 경로의 마지막엔 슬래시(/) 사용 금지
하이픈(-)은 url 가독성을 높이는데 사용
밑줄(_)은 url에 사용 금지
url 경로에는 소문자가 적합
=> kebab-case
2xx (성공) : 요청이 성공한 경우 (ex 200 : 성공)
3xx(리다이렉션) (ex 301 : 영구 이동)
4xx(요청 오류) : 클라이언트가 잘못 요청한 경우) => 프론트
400 : Bad Request(잘못된 요청 : 클라이언트의 요청이 잘못됨)
401 : Unauthorized(권한 없음 : 인증이 안된 상태, 로그인 필요)
403 : Forbidden(금지됨 : 해당 자원에 접근할 권한 없음)
404 : Not Found(찾을 수 없음 : 요청한 자원이 없다. Page Not Found)
5xx(서버 오류) => 백엔드
500 : Internal Server Error (내부 서버 오류 : 서버에서 오류가 발생하였음, 코드가 잘못된 경우)
JSON
"key": "value" (숫자인 경우 "key": value)
- key 값은 무조건 "" 안에
- value엔 문자, 숫자, 객체, 리스트, boolean, null 등이 들어갈 수 있음
- 리스트 안에도 다 들어감(문자, 숫자, 객체, boolean, 리스트 , null 등)
- 대부분 camelCase 사용
JWT(Json Web Token)
token ex) 로그인 할 때 사용
.을 기준으로 세 영역으로 분리
설명 : https://velopert.com/2389
Base64 인코딩 : 날짜인데 문자열이 나온 경우
검색해도 잘 안나오는 정보 모음
const user = {
name : Min
role : leader
}
user['role'] = 'leader' => 텍스트 (얜 없는 것도 포함할 수 있다)
user.role = 'leader' => 코드 (얜 있는 것만)
const { role } = user ( { role } === user.role )
const { role2 = 'abc' } =user ( if문의 효과 : role2가 존재하지 않으면 디폴트로 abc를 넣어라)
const user = {
username: 'Min',
role: 'member'
};
const user2 = {
username, // 이건 다음과 같다 username: username,(위의 username)
role // role: role(위의 role)
};
console.log('user2', user2) // 콘솔로그 결과: user2 {username: 'Min', role: 'member'}
for문
const userList = [
{ name: 'a', nick: 'aa' },
{ name: 'a', nick: 'aa' },
{ name: 'a', nick: 'aa' },
{ name: 'a', nick: 'aa' }
];
for (let i = 0; i < userList.length; i += 1) // length는 위의 항목이 총 4개이므로 4이다
for문 + if문
const userList = [
{ name: 'a', nick: 'aa' },
{ name: 'a', nick: 'aa' },
{ name: 'a', nick: 'aa' },
{ name: 'a', nick: 'aa' }
];
for (let i = 0; i < userList.length; i += 1) { // length는 위의 항목이 총 4개이므로 4이다 {
const user = userList[i]
console.log('user', user)
if (user.name === 'a') {
console.log('this is My friend', user)
}
break; // break를 안걸면 결과 찾아도 4번 다 돈다
}
위 : 브레이크 없음
아래 : 브레이크 있음
Node js
자바스크립트 엔진(엔진이라 서버 가능)
node (자바스크립트파일명).js
하면 실행됨
코드 추적 방법
처음 파일 받으면 .env, ~config 파일 등에 설정이 다 있으니 확인하면 됨
그 중에서도 모르는 게 있으면 전체검색하면 나옴
Proxy 에러
500 에러가 뜨고, 네트워크를 확인해보면 프록시 에러가 뜬다.
결론부터 말하면 백엔드 서버가 실행이 안돼서 발생하는 에러다.
Side Bar에 현재 위치 표시, 현재 위치에 접속한 경우 링크 클릭 방지
3일 내내 고심했는데 어떻게든 작동시켰다.
에러를 정말 많이 봤다.
1. 제일 처음 본 에러
맨 처음 테스트데이터를 넣는데 링크 내의 내용이 떴다. 친절하게 설명이 나와있어 그대로 따라했다. 해결~
2. NavigationDuplicated 에러
if (this.$router.currentRoute.name !== 'routeName1') {
this.$router.push({
name: 'routeName2',
})
}
링크를 참고했다.
그냥 this.$router.path 를 쓰면 안되고 this.$router.currentRoute.path 를 쓰면 된다.
검색해보니 currentRoute : 현재 라우트에 대한 Route 객체라고 설명되어있는데 아마 그 차이인 것 같다.
근데 아직 이상한 점이 있다.
현재 위치의 console.log를 출력하는 함수
methods: {
whereAmI() {
console.log(this.$route.path)
}
}
를 <template>안에서 호출하지 않으면 disabled와 active가 바로바로 작동하질 않는다.
내 생각엔 $router.push(주소)를 해주는 @click이 :disabled, :active 랑 순서가 안맞는 것 같다.
이유는 click은 정상 작동 하지만 :disabled, :active는 새로고침해야 둘다 작동하기 때문이다.
해결했다!
결론부터 적자면 그냥 $route.path로도 작동 잘 했다.
작동이 안된 이유는 오타였다.
$route를 $router로 적었다...(위의 코드를 복붙하고 수정을 제대로 못한 것이다)
복붙하고 수정할 때 꼭 코드를 모두 확인하는 습관을 들이도록 하자^^
+ 추가 220109
저렇게 혼자 if문으로 해놓고 결과적으로 내 코드를 보신 강사님의 삼항 연산자를 써보라는 힌트에 삼항연산자를 구글링해서 혼자 어찌저찌 구현했다.
코드는 아래와 같았다.
<template>
<div>
<b-list-group>
<b-list-group-item
href="#"
:disabled="this.$route.path === '/dashboard' ? true : false"
:style="this.$route.path === '/dashboard' ? 'background-color: #87CEEB' : 'background-color: white'"
@click="$router.push('/dashboard')"
>대시보드
</b-list-group-item>
<b-list-group-item
href="#"
:disabled="this.$route.path === '/department' ? true : false"
:style="this.$route.path === '/department' ? 'background-color: #87CEEB' : 'background-color: white'"
@click="$router.push('/department')"
>부서 관리
</b-list-group-item>
<b-list-group-item
href="#"
:disabled="this.$route.path === '/user' ? true : false"
:style="this.$route.path === '/user' ? 'background-color: #87CEEB' : 'background-color: white'"
@click="$router.push('/user')"
>사용자 관리
</b-list-group-item>
<b-list-group-item
href="#"
:disabled="this.$route.path === '/device' ? true : false"
:style="this.$route.path === '/device' ? 'background-color: #87CEEB' : 'background-color: white'"
@click="$router.push('/device')"
>장비 관리
</b-list-group-item>
</b-list-group>
</div>
</template>
<script>
</script>
그리고 백엔드, db와 연동하는 복습을 끝낸 오늘...
백엔드를 복기하다가 문득 disabled를 삼항 쓰지 않아도 된다는 강사님의 코멘트가 생각났다.
부랴부랴 켜서 이것저것 해보다(대충 붙이니까 eslint 에러가 참 많이 났다...가차 없다) 수정했다.
원래 내 코드는 이랬다.
<b-list-group-item
href="#"
:disabled="this.$route.path === '/department' ? true : false"
:style="this.$route.path === '/department' ? 'background-color: #87CEEB' : 'background-color: white'"
@click="$router.push('/department')"
>부서 관리
</b-list-group-item>
disabled에도 style처럼 삼항 연산자를 써서 클릭하여 들어가는 주소가 해당 주소와 일치하면 조건이 실행 되도록 했었다.
근데 한방에 가능하다는 멘트를 떠올리며 다음과 같이 수정했다.
<b-list-group-item
href="#"
:disabled="this.$route.path === '/dashboard'"
:style="this.$route.path === '/dashboard' ? 'background-color: #87CEEB' : 'background-color: white'"
@click="$router.push('/dashboard')"
>대시보드
</b-list-group-item>
결과는 잘 됐다. 생각해보니 저 조건만 넣어도 잘 동작하는 게 맞았다.
disabled는 style처럼 다른 색을 표시하는 등 구체적인 명령이 필요가 없었다. 그냥 해당 라우터와 일치하면 작동해라. 이 조건만 충족하면 됐다.
처음 할 땐 if를 써야하는지 뭘 써야하는지도 몰랐고, 삼항연산자도 뭔지 몰라서 구글링하며 이해하려고 애썼는데...나름 성장하고 있는 것 같아 뿌듯하다.