μΉ΄ν…Œκ³ λ¦¬ μ—†μŒ

[ KB IT's Your Life 7κΈ° ] μ„œλ²„μ‚¬μ΄λ“œ μ»΄ν¬λ„ŒνŠΈ λ°±μ—”λ“œ 개발 ν›„κΈ° | κ²Œμ‹œνŒ μˆ˜μ •κ³Ό 인증 κ°€λ“œ

yeye 2026. 7. 9. 17:34

μ•ˆλ…•ν•˜μ„Έμš”!
KB IT's Your Life 7κΈ° κΈ°μžλ‹¨ μž…λ‹ˆλ‹€
이제 μ •κ·œ μˆ˜μ—…μ€ λμ΄λ‚˜κ³  νŒŒμ΄λ„ ν”„λ‘œμ νŠΈμ—
λ“€μ–΄κ°€λŠ” μ‹œκΈ°λ„€μš”!!!
벌써 μ‹œκ°„μ΄ μ΄λ ‡κ²Œλ‚˜ μ§€λ‚¬λ‹€λ‹ˆ....μ‹œκ°„μ΄ λΉ λ₯΄λ©΄ μ—΄μ‹¬νžˆ μ‚΄κ³ μžˆλ‹€λŠ” 증거라고 μƒκ°ν•˜κ³  λ”λ”μš± μ—΄μ‹¬νžˆ κ°œλ°œν•˜κ² μŠ΅λ‹ˆλ‹€><

이번 μ‹œκ°„μ—λŠ” κ²Œμ‹œνŒ μˆ˜μ • νŽ˜μ΄μ§€λ₯Ό λ§ˆλ¬΄λ¦¬ν•˜κ³  인증 κ°€λ“œκΉŒμ§€ λΆ™μ΄λŠ” μž‘μ—…μ„ ν–ˆμ–΄μš”!!!
κΈ°λŠ₯ ν•˜λ‚˜μ”© λΆ™μ—¬λ‚˜κ°€λ‹€ λ³΄λ‹ˆκΉŒ 이제 μ§„μ§œ μ„œλΉ„μŠ€ κ°™μ•„ 보이기 μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€.

κ²Œμ‹œνŒ μˆ˜μ • νŽ˜μ΄μ§€ 마무리

μˆ˜μ • νŽ˜μ΄μ§€μ—μ„œ 기본적으둜 ν•„μš”ν•œ 것듀뢀터 μ€€λΉ„ν–ˆμ–΄μš”.

λ°˜μ‘ν˜• 데이터λ₯Ό μœ„ν•œ ref, reactive, ν˜„μž¬ κΈ€ 번호λ₯Ό μ•ŒκΈ° μœ„ν•œ useRoute, μˆ˜μ • μ™„λ£Œ ν›„ 이동을 μœ„ν•œ useRouter β€” 거의 항상 이 두 κ°œκ°€ μ„ΈνŠΈλ‘œ λ”°λΌλ‹€λ‹™λ‹ˆλ‹€.

const route = useRoute()
const router = useRouter()
const articleNo = route.params.articleNo

상세 보기, μˆ˜μ •, μ‚­μ œ νŽ˜μ΄μ§€μ—μ„œλŠ” 항상 이 라인이 ν•„μš”ν•˜λ‹€κ³  κ°•μ‘°ν•˜μ…¨μ–΄μš”.


μ²¨λΆ€νŒŒμΌ μ‚­μ œ β€” findIndex + splice

κΈ°μ‘΄ μ²¨λΆ€νŒŒμΌμ„ μ‚­μ œν•  λ•Œ λ°°μ—΄ 쀑간 μš”μ†Œλ₯Ό μ œκ±°ν•΄μ•Ό ν•˜λŠ”λ°, μ΄λ•Œ findIndex둜 μœ„μΉ˜λ₯Ό μ°Ύκ³  splice둜 μ‚­μ œν•˜λŠ” νŒ¨ν„΄μ„ λ°°μ› μ–΄μš”.

const idx = attachments.value.findIndex(f => f.no === fileNo)
attachments.value.splice(idx, 1)

μ„œλ²„μ—μ„œ λ¨Όμ € μ‚­μ œν•˜κ³ , κ·Έλ‹€μŒ ν΄λΌμ΄μ–ΈνŠΈ λ°°μ—΄μ—μ„œλ„ μ œκ±°ν•˜λŠ” μˆœμ„œκ°€ μ€‘μš”ν•©λ‹ˆλ‹€.


이벀트 ν•Έλ“€λŸ¬μ— λ§€κ°œλ³€μˆ˜ λ„˜κΈ°κΈ°

클릭 이벀트 ν•Έλ“€λŸ¬λ₯Ό μ—°κ²°ν•  λ•Œ ν‰μ†Œμ—λŠ” ν•¨μˆ˜λͺ…λ§Œ 적으면 이벀트 객체가 μžλ™μœΌλ‘œ μ „λ‹¬λΌμš”.
근데 μ΄λ²ˆμ—λŠ” 파일 번호 같은 μ»€μŠ€ν…€ λ§€κ°œλ³€μˆ˜λ₯Ό λ„˜κ²¨μ•Ό ν–ˆλŠ”λ°, 그럴 λ•ŒλŠ” 호좜문 ν˜•νƒœλ‘œ 써야 ν•©λ‹ˆλ‹€.

<!-- λ§€κ°œλ³€μˆ˜ 없을 λ•Œ -->
@click="handleSubmit"

<!-- λ§€κ°œλ³€μˆ˜ μžˆμ„ λ•Œ -->
@click="removeFile(file.no, file.name)"

이벀트 객체도 같이 λ„˜κΈ°κ³  μ‹Άλ‹€λ©΄ $eventλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μΆ”κ°€ν•˜λ©΄ λΌμš”.


SPAμ—μ„œ 파일 λ‹€μš΄λ‘œλ“œ β€” 동적 aνƒœκ·Έ

SPA ν™˜κ²½μ—μ„œλŠ” <a> νƒœκ·Έλ₯Ό 직접 HTML에 λ‘λŠ” κ±Έ ꢌμž₯ν•˜μ§€ μ•Šμ•„μš”. 잘λͺ» 닀루면 앱이 리셋될 수 μžˆκ±°λ“ μš”.

κ·Έλž˜μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ λ™μ μœΌλ‘œ λ§Œλ“€μ—ˆλ‹€ μ œκ±°ν•˜λŠ” 방식을 μ”λ‹ˆλ‹€.

const a = document.createElement('a')
a.href = downloadUrl
document.body.appendChild(a)
a.click()
document.body.removeChild(a)

화면에 보이지 μ•Šκ²Œ μΆ”κ°€ν–ˆλ‹€κ°€ 클릭을 κ°•μ œλ‘œ λ°œμƒμ‹œν‚€κ³  λ°”λ‘œ μ œκ±°ν•˜λŠ” κ±°μ˜ˆμš”.


인증 κ°€λ“œ β€” beforeEnter

둜그인 μ•ˆ ν•œ μƒνƒœμ—μ„œ κΈ€μ“°κΈ° νŽ˜μ΄μ§€μ— λ°”λ‘œ μ ‘κ·Όν•  수 μžˆλŠ” λ¬Έμ œκ°€ μžˆμ—ˆμ–΄μš”.
이걸 λ§‰μ•„μ£ΌλŠ” 게 인증 κ°€λ“œμž…λ‹ˆλ‹€.

util/guards.js νŒŒμΌμ„ λ§Œλ“€κ³  isAuthenticated ν•¨μˆ˜λ₯Ό μ •μ˜ν–ˆμ–΄μš”.

export function isAuthenticated(to, from) {
  const authStore = useAuthStore()
  if (authStore.isAuthenticated) return

  return {
    name: 'login',
    query: { next: to.name }
  }
}

둜그인이 λ˜μ–΄ 있으면 κ·Έλƒ₯ 톡과, μ•ˆ λ˜μ–΄ 있으면 둜그인 νŽ˜μ΄μ§€λ‘œ λ³΄λ‚΄λ©΄μ„œ next 쿼리에 μ›λž˜ λͺ©μ μ§€λ₯Ό λ‹΄μ•„μš”.


둜그인 성곡 ν›„ μ›λž˜ νŽ˜μ΄μ§€λ‘œ 이동

κ°€λ“œλ§Œ λ§Œλ“€λ©΄ 끝이 μ•„λ‹ˆμ—μš”. 둜그인 성곡 후에 μ›λž˜ κ°€λ €λ˜ νŽ˜μ΄μ§€λ‘œ λŒμ•„κ°€λŠ” μ²˜λ¦¬λ„ 직접 ν•΄μ€˜μ•Ό ν•©λ‹ˆλ‹€.

const next = route.query.next
if (next) {
  router.push({ name: next })
} else {
  router.push({ name: 'home' })
}

next 쿼리가 있으면 거기둜, μ—†μœΌλ©΄ ν™ˆμœΌλ‘œ κ°€λŠ” κ΅¬μ‘°μ˜ˆμš”.
κ°€λ“œλŠ” 체크만 해쀄 뿐, 둜그인 이후 흐름은 κ°œλ°œμžκ°€ 직접 ꡬ성해야 ν•œλ‹€λŠ” 점이 μΈμƒμ μ΄μ—ˆμŠ΅λ‹ˆλ‹€.


이번 μ£ΌλŠ” μˆ˜μ • κΈ°λŠ₯λΆ€ν„° 인증 μ²˜λ¦¬κΉŒμ§€, μ‹€μ œ μ„œλΉ„μŠ€μ—μ„œ λ‹Ήμ—°ν•˜κ²Œ μ“°μ΄λŠ” κΈ°λŠ₯듀을 직접 λ§Œλ“€μ–΄λ΄€μ–΄μš”.
λ‹Ήμ—°ν•˜κ²Œ μ“°λ˜ 게 μ΄λ ‡κ²Œ λ§Œλ“€μ–΄μ§€λŠ” κ±°μ˜€κ΅¬λ‚˜ μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒ κΈ€ λΆ€ν„°λŠ” ν”„λ‘œμ νŠΈ ν›„κΈ°λ₯Ό μ“Έκ±΄λ°μš”!
λ²Œμ¨λΆ€ν„° λ„ˆλ¬΄ μ„€λ ˆκ³  λ–¨λ¦½λ‹ˆλ‹€!γ…Žγ…Žγ…Ž λ‹€μŒ 글도 많이 κΈ°λŒ€ν•΄μ£Όμ„Έμš”
μ½μ–΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€ πŸ’›