๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ฐœ๋ฐœ/Vue.js

Vue ๋ผ์šฐํ„ฐ / SPA / Router ๊ฐ’ ์ „๋‹ฌ

by 1mj 2022. 4. 4.

SPA (Single Page Application)

์ผ๋ฐ˜์ ์ธ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›น ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋ฉด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ html ์„ ์ „๋‹ฌ ๋ฐ›์•„ ๋ Œ๋”๋ง ์—”์ง„์„ ํ†ตํ•ด ํ™”๋ฉด์— ๋ณด์—ฌ์ค€๋‹ค. ํ•œ ํŽ˜์ด์ง€์— ํ•ด๋‹นํ•˜๋Š” ํŽ˜์ด์ง€ ์šฉ๋Ÿ‰์ด ์ปค์ง€๋ฉด ์š”์ฒญ๋งˆ๋‹ค ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ์ „๋‹ฌ ๋ฐ›๊ธฐ ๋ฒ„๊ฒ๋‹ค.

 

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด SPA, Single Page Application ์ด๋‹ค. SPA ๋Š” ๋‹จ์ผ ํŽ˜์ด์ง€๋กœ ๊ตฌ์„ฑ๋œ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์ „์ฒด ํŽ˜์ด์ง€๋ฅผ ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์— ๋‹ด์•„ ๋™์ ์œผ๋กœ ํ™”๋ฉด์„ ๋ฐ”๊ฟ”๊ฐ€๋ฉฐ ํ‘œํ˜„ํ•œ๋‹ค. ํŽ˜์ด์ง€ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚œ๋‹ค๋Š” ๊ฒƒ์ด ์ตœ์ดˆ ๋กœ๋“œ๋˜์—ˆ์„ ๋•Œ ๋ฏธ๋ฆฌ ๋ธŒ๋ผ์šฐ์ €์— ์˜ฌ๋ผ๊ฐ„ ํ…œํ”Œ๋ฆฟ๋งŒ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ํ™”๋ฉด ์ด๋™ ์‹œ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ html ๋กœ ์ „๋‹ฌ(์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง) ๋ฐ›์ง€ ์•Š๊ณ  ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ ๋ฐ›์•„ ๋™์ ์œผ๋กœ ๋ Œ๋”๋ง ํ•œ๋‹ค. 

 

MPA(Multiple Page Application) vs SPA(Single Page Application)

 

๋Œ€ํ‘œ์ ์ธ SPA ํ”„๋ ˆ์ž„์›Œํฌ๋Š” Angular, React, Vue ๋“ฑ์ด ์žˆ๋‹ค. SPA ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ธํ•œ DOM ์กฐ์ž‘์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜ ๋ธŒ๋ผ์šฐ์ €์˜ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚จ๋‹ค๋Š” ๋ฌธ์ œ์ ์ด ์žˆ์–ด ๊ฐ€์ƒ DOM(Virtual DOM)์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ฐ€์ƒ ๋”์„ ์‚ฌ์šฉํ•˜๋ฉด DOM ํŠธ๋ฆฌ์™€ ์œ ์‚ฌํ•œ ๊ฐ€์ƒ์˜ ๊ฐ์ฒด ํŠธ๋ฆฌ๋กœ html ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋‹ค๊ฐ€ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ชจ๋“  ๋ณ€ํ™”๋ฅผ ๋ชจ์•„ ํ•œ ๋ฒˆ์— ํ™”๋ฉด์„ ๊ฐฑ์‹ ํ•œ๋‹ค.

 


Vue Router ๋ž€?

Vue ์—์„œ ํ™”๋ฉด์„ ์ „ํ™˜ํ•  ๋•Œ๋Š” router ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋ผ์šฐํ„ฐ๋Š” ํŠน์ • ์ฃผ์†Œ์™€ ์ ‘๊ทผํ•  ํŽ˜์ด์ง€ ์ •๋ณด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŠน์ • ์ฃผ์†Œ๋กœ ์ ‘๊ทผํ•  ๊ฒฝ์šฐ ์ด์— ํ•ด๋‹นํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ฒƒ์„ ๋ผ์šฐํ„ฐ์—์„œ ๋ผ์šฐํŠธ๋ฅผ ์„ค์ •ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

 

์ •ํ™•ํ•˜๊ฒŒ๋Š” ํŽ˜์ด์ง€๋ฅผ '์ „ํ™˜' ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ํŽ˜์ด์ง€ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ๋“ค์„ '์žฌ๋ฐฐ์น˜' ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

url ๋ณ€๊ฒฝ ์‹œ DOM ์„ ์ƒˆ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฏธ๋ฆฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ฐ€ ๋ณ€๊ฒฝ๋œ ์š”์†Œ ์˜์—ญ๋งŒ ๊ฐฑ์‹ ํ•˜์—ฌ ์œ ์—ฐํ•œ ํŽ˜์ด์ง€ ์ „ํ™˜์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

vue ์—์„œ๋Š” vue-router ๋ผ๋Š” ๋ผ์šฐํŒ… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง€์›ํ•œ๋‹ค.

 

- ๋ผ์šฐํ„ฐ ์„ค์น˜ํ•˜๊ธฐ

vue-router๋ฅผ ์„ค์น˜ํ•˜๊ณ  package.json ํŒŒ์ผ์—์„œ ์ถ”๊ฐ€๋œ ๋ชจ๋“ˆ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

 

npm install vue-router --save

 

- ๋ผ์šฐํ„ฐ ์†์„ฑ

์†์„ฑ ํ•˜์œ„ ์†์„ฑ ์†์„ฑ ๊ฐ’  
mode hash (default) ๋ชจ๋“  URL ์„ hash(#) ํ˜•ํƒœ๋กœ ์„œ๋น„์Šค, URL ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค์‹œ ๋กœ๋“œ๋˜์ง€ ์•Š์Œ
history ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜์ง€ ์•Š๊ณ  URL ํƒ์ƒ‰ ๊ฐ€๋Šฅ
redirect ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
routes path url ๊ฒฝ๋กœ
component ํ•ด๋‹น url ์— ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ
children ์ค‘์ฒฉ ๋ผ์šฐํŒ… ๋ฐฐ์—ด
alias ๋ณ„์นญ

 

- ๋ผ์šฐํ„ฐ ๋™์ž‘ ํ๋ฆ„

โ‘  ์›น ์‚ฌ์ดํŠธ๋ฅผ ์—ด๋ฉด public > index.html ํŒŒ์ผ๋งŒ ๋ Œ๋”๋ง ๋จ

โ‘ก Vue ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ โ‘  ์˜ ํƒœ๊ทธ์™€ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—ฐ๊ฒฐ๋˜๊ณ  render function ์—์„œ App ์ด๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณด์—ฌ์ง

โ‘ข src > App.vue ์—์„œ ๋ผ์šฐํ„ฐ๋กœ ํŽ˜์ด์ง€๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์žˆ์Œ

<router-link> ๊ฐ€ <a> ํƒœ๊ทธ๋กœ ๋ฐ”๋€Œ์–ด์„œ ์‹คํ–‰๋จ

โ‘ฃ ๋ผ์šฐํ„ฐ์— ๊ด€๋ จ๋œ ์„ค์ •์€ router > index.js ์—์„œ ์ง€์ •๋œ ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ํ•ด๋‹น ๊ฒฝ๋กœ๋ฅผ ๋ณด์—ฌ์คŒ

 

 

Router ๊ธฐ๋ณธ

- ๋ผ์šฐํŒ… ๊ธฐ๋Šฅ์„ ์ด์šฉํ•œ ํŽ˜์ด์ง€ ์ด๋™ <router-link>

<route-link to="url"> : ํŽ˜์ด์ง€ ์ด๋™ ํƒœ๊ทธ, ํ™”๋ฉด์—์„œ๋Š” <a> ํƒœ๊ทธ๋กœ ์น˜ํ™˜

<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>

 

- ๋ผ์šฐํŒ… ํŽ˜์ด์ง€ ํ‘œ์‹œ <router-view>

<route-view> : ํŽ˜์ด์ง€ ํ‘œ์‹œ ํƒœ๊ทธ, ๋ณ€๊ฒฝ๋˜๋Š” url์— ๋Œ€ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฟŒ๋ ค์คŒ

<router-view></router-view>

 

- ๋„ค๋น„๊ฒŒ์ด์…˜ url ์ด๋™ ๋ฐฉ์‹ ๋น„๊ต

์„ ์–ธ์ „ ๋ฐฉ์‹ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ํŠน์ง•
<router-link:to="..."> router.push(...) ์ƒˆ๋กœ์šด URL ์„ ํžˆ์Šคํ† ๋ฆฌ ์Šคํƒ์— ๋„ฃ์–ด ๋ธŒ๋ผ์šฐ์ €์˜ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ด์ „ URL ๋กœ ์ด๋™
<router-link:to="..." replace> router.replace(...) ์ƒˆ๋กœ์šด URL ์„ ํžˆ์Šคํ† ๋ฆฌ ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ํ˜„์žฌ URL ์„ ๋Œ€์ฒด
- router.go(n) ํžˆ์Šคํ† ๋ฆฌ ์Šคํƒ์—์„œ n ๋งŒํผ ์•ž, ๋’ค๋กœ ์ด๋™

 

- ๋ผ์šฐํ„ฐ์˜ ๊ธฐ๋ณธ ๊ฒฝ๋กœ

'๋ฃจํŠธ url'/#/'๋ผ์šฐํ„ฐ ์ด๋ฆ„'

๊ธฐ๋ณธ ๊ฒฝ๋กœ์— '#' ๊ฐ’์„ ์ œ์™ธํ•˜๊ณ  ์‹ถ์œผ๋ฉด mode๋ฅผ history๋กœ ์„ค์ •

 

- Nested Routers vs Named Views

ํŠน์ • url ์— ์ง€์ •๋œ 1๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์„ Nested Router, ํŠน์ • url ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜์—ญ ๋ณ„๋กœ ์ง€์ •ํ•˜์—ฌ ๋ Œ๋”๋ง ํ•˜๋Š” ๊ฒƒ์„ Named View ๋ผ๊ณ  ํ•œ๋‹ค.

  • Nested: ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ํ˜•์‹
  • Named: ๊ฐ™์€ ๋ ˆ๋ฒจ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ํ‘œ์‹œ

 

- ๋ผ์šฐํ„ฐ๋กœ ๊ฐ’ ์ „๋‹ฌํ•˜๊ธฐ

๋ผ์šฐํ„ฐ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด์„œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์— ๋™์ ์œผ๋กœ ํ•„์š”ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒฝ์šฐ path ๋ฅผ ํ†ตํ•œ ๊ฐ’ ์ „๋‹ฌ, params ๋ฅผ ํ†ตํ•œ ๊ฐ’ ์ „๋‹ฌ์˜ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค

 

โ‘  path ๋ฅผ ํ†ตํ•œ ๊ฐ’ ์ „๋‹ฌ

// router.push()์˜ ์ธ์ž๋กœ path๋ฅผ ๋„˜๊ธธ ๋•Œ key=value๋ฅผ ์ž‘์„ฑ
router.push("/login?id=test@naver.com");

// path๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ๋ฐ›๊ธฐ ์œ„ํ•ด vue ๊ฐ์ฒด์˜ query ์ด์šฉ
this.$route.query.key

 

โ‘ก params ๋ฅผ ํ†ตํ•œ ๊ฐ’ ์ „๋‹ฌ

  • url ๊ฒฝ๋กœ์— ๋…ธ์ถœ๋˜์ง€ ์•Š๊ณ  ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจ ํ•˜๊ฑฐ๋‚˜ ๋ฆฌ๋กœ๋“œํ•  ๋•Œ ๊ฐ’์ด ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค.
  • path ์™€ param ์€ ๊ฐ™์ด ์ž‘๋™๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ name ์„ ์ด์šฉํ•œ๋‹ค.
// name๊ณผ props:true ์ถ”๊ฐ€
routes: [
    {
        name: 'login',
        path: '/login',
        component: Login,
        props: true
    }
]

// path ๋Œ€์‹  name์„ ์ด์šฉํ•ด ์–ด๋–ค ๊ฒฝ๋กœ๋กœ ๊ฐˆ์ง€ ๊ฒฐ์ •, params๋ฅผ ์ด์šฉํ•ด ์ „๋‹ฌํ•œ ๊ฐ’์„ ์•Œ๋ ค์คŒ
router.push({name:"login", params:{"id":"test@naver.com"}}});

// this.$route.params.key ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ๋ฐ›์Œ
this.$route.params.id

 

 

์ฐธ๊ณ ์ž๋ฃŒ ๋ฐ ์ถœ์ฒ˜ ๐Ÿ™‡‍โ™‚๏ธ

https://www.huskyhoochu.com/what-is-spa/

 

๋Œ“๊ธ€