[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์šฉํ•˜์—ฌ ์‡ผํ•‘ ์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€์™€ ์ƒ์„ธ ํŽ˜์ด์ง€ ๊ฐœ๋ฐœ

2022. 5. 24. 05:30ใ†Front-End ์ž‘์—…์‹ค/Nuxt.js

728x90
๋ฐ˜์‘ํ˜•

 

Git Hub

 

 

 

 

 

ํ•œ ๊ถŒ์œผ๋กœ ๋ฐฐ์šฐ๋Š” Vue js 3 ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ๊ธฐ์ดˆ ์‹ค์ „ (์˜์ง„์ฑ…)

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

๐Ÿ—‚ ๋ชฉ์ฐจ

โ— [Vue+Nuxt.js] Nuxt.js ๊ธฐ๋ณธ 
โ—[Vue+Nuxt.js] Nuxt.js ์‹œ์ž‘ํ•˜๊ธฐ 
โ— [Vue+Nuxt.js] Nuxt.js Data ํ˜ธ์ถœ ๋ฐฉ์‹๊ณผ API ์—ฐ๋™  
โ—[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์šฉํ•˜์—ฌ ์‡ผํ•‘ ์ƒํ’ˆ ๋ชฉ๋ก ํŽ˜์ด์ง€์™€ ์ƒ์„ธ ํŽ˜์ด์ง€ ๊ฐœ๋ฐœ
โ— [Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์šฉํ•˜์—ฌ ์‡ผํ•‘ ์ƒํ’ˆ ๊ฒ€์ƒ‰ UI ๊ฐœ๋ฐœ
โ—[Vue+Nuxt.js] Vuex๋ฅผ ์ด์šฉํ•˜์—ฌ ์žฅ๋ฐ”๊ตฌ๋‹ˆ Page ๋งŒ๋“ค๊ธฐ
โ— [Vue+Nuxt.js] Vuex ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ์ดˆ๊ธฐํ™” ๋˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ

 

 

๐Ÿ—‚ ๋ถ€๋ก

โ— [FrontEnd] HMR(Hot Module Replacement)
โ— [Nuxt.js] ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ํ˜ธ์ถœ ๋ฐฉ๋ฒ•

โ— V-Model ๋™์ž‘ ์›๋ฆฌ์™€ ํ™œ์šฉ ๋ฐฉ๋ฒ•
โ— [Nuxt.js] NuxtServerInit

 

 

๐Ÿ—‚ ๋‚ด๊ฐ€ ๋งŒ๋‚œ Error

โ— [vuex] expects string as the type, but found undefined.

 

 

 

 

 

 

 

๐Ÿš€ Nuxt.js๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๊ธฐ

    ๐Ÿ”ฝ  ์ƒํ’ˆ Page

        ๐Ÿ“ฆ ์ƒํ’ˆ ๋ชฉ๋ก ํ‘œ์‹œ ๊ธฐ๋Šฅ ๊ตฌํ˜„

์ตœ์ดˆ Back End๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒํ’ˆ ๋ชฉ๋ก์„ ์˜ˆ์˜๊ฒŒ ํ•œ๋ฒˆ ์ถœ๋ ฅ ํ•ด ๋ณผ๊ฒŒ์š”.

/pages/main.vue

๋จผ์ € `<ul>` Tag๋ฅผ ๊ฐ์‹ผ ๋’ค 7๋ฒˆ์งธ ์ค„์— `<li>` Tag๋ฅผ ์ด์šฉํ•˜์—ฌ `v-for`๋ฅผ ํ†ตํ•ด 28๋ฒˆ์งธ ์ค„์—์„œ ๋ฐ˜ํ™˜๋œ `products`์— ๋ชฉ๋ก์„ `product`๋ผ๋Š” ๋ณ€์ˆ˜์— for๋ฌธ์ด ๋Œ๋ฉด์„œ ๋‹ด๊ธฐ๊ฒŒ ํ•˜๊ณ , `product`์˜ id๊ฐ’์„ `:key`๋ฅผ ์ด์šฉํ•˜์—ฌ Unique ๊ฐ’์„ ์ง€์ •ํ•ด ์ฃผ์—ˆ์–ด์š”. 

๊ทธ๋Ÿฐ ๋’ค ํ•ด๋‹น ๋‚ด์šฉ์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ 8๋ฒˆ์งธ ์ค„๊ณผ ๊ฐ™์ด ์ž‘์—…์„ ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

http://localhost:4000/main

์•„์ฃผ ์˜ˆ์˜๊ฒŒ ์ •๋ ฌ์ด ๋˜์„œ ์ถœ๋ ฅ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.

์œ„์˜ ๋‚ด์šฉ์„ ๋ณด๋ฉด Image๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด Image๋ฅผ ํ™”๋ฉด์— ๊ทธ๋ ค์ฃผ๋ฉด์„œ ๊ทธ Image ๋ฐ‘์— ์ด๋ฆ„๊ณผ ๊ฐ€๊ฒฉ ์ •๋ณด๋ฅผ ํ•œ๋ฒˆ ์ถœ๋ ฅํ•ด ๋ณผ๊ฒŒ์š”!


/pages/main.vue

์ถ”๊ฐ€๋œ ๋ถ€๋ถ„์€ 10 ~ 14๋ฒˆ์งธ ์ค„์ด์—์š”. ๋จผ์ € `<img>` Tag๋ฅผ ํ†ตํ•ด Image ์œ„์น˜(:src)๋ฅผ ์ง€์ •ํ•ด ์ฃผ๊ณ , ํ•ด๋‹น Image๊ฐ€ ์ถœ๋ ฅ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ๋Œ€์ฒด Text ๊ฐ’ (: alt)์„ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋’ค ์‚ฌ์ง„ ๋ฐ‘์— ์ด๋ฆ„๊ณผ ๊ฐ€๊ฒฉ์ด ํ‘œ์‹œ๋˜๋„๋ก ์ž‘์—…์„ ํ•ด ์ฃผ์—ˆ์–ด์š”.


http://localhost:4000/main


๋ฐ‘์— ๋” ์žˆ์ง€๋งŒ, ์ด ๋ถ€๋ถ„๋งŒ ์˜ฌ๋ ค ๋†“๋„๋ก ํ• ๊ฒŒ์š”.

๋ฌธ์ œ๋Š” ํ˜„์žฌ ์‚ฌ์ง„์ด ๋ชจ๋‘ ๊ฐ™์€ ๊ฒƒ์ด ์ถœ๋ ฅ๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์—์š”.
์ด ๋ถ€๋ถ„์€ API๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„œ๋ฒ„์— ํŠน์„ฑ ๋•Œ๋ฌธ์ธ๋ฐ, ์ด๋ฅผ ๋‹ฌ๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์กฐ๊ธˆ ์ˆ˜์ •์„ ํ•ด ๋ณผ๊ฒŒ์š”.

/pages/main.vue


์œ„์™€ ๊ฐ™์ด 47๋ฒˆ์งธ ์ค„์— API ์‘๋‹ต๊ฐ’์œผ๋กœ ๋ฐ›์•„์˜จ ๊ฐ’์˜ ๋ชฉ๋ก ๋ฐฐ์—ด ๊ฐ’(data)์— `map()`๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ๊ฐ์˜ ๋ฐฐ์—ด ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ ๋ฐ›๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€๋ฅผ ํ•˜๊ณ , ์—ฌ๊ธฐ์— item์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์–ด์ค€ ๋’ค Body์— ๋ฐ˜ํ™˜ ๋‚ด์šฉ์œผ๋กœ ์ตœ์ดˆ 49๋ฒˆ์งธ ์ค„์— ์ธ์ž๊ฐ’์œผ๋กœ ์ž…๋ ฅ๋œ item์— ๋“ค์–ด ์žˆ๋Š” id, name, image, price ์ •๋ณด๋ฅผ ํ’€์–ด ๊ฐ์ฒด(key : value)๋กœ ์ €์žฅํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค 51๋ฒˆ์งธ ์ค„์— `imageUrl` ๊ฐ์ฒด์— item์•ˆ์— ์žˆ๋Š” imageUrl์— random ํ•จ์ˆ˜๋ฅผ ๋Œ๋ ค Image๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์ด ์ถœ๋ ฅ๋˜๋„๋ก ํ•ด ์ค€ ๊ฒƒ์ด์—์š”.

 

 

 

 

 

        ๐Ÿ“ฆ Routing ๋ฐ Styling

์ตœ์ดˆ `main.vue`์— ์žˆ๋˜ ๋ชจ๋“  Code๋ฅผ 'index.vue'์— ์˜ฎ๊ฒจ ์ฃผ๊ณ , `main.vue`๋Š” ์‚ญ์ œ ํ•ด ์ฃผ์„ธ์š”.
๊ทธ๋Ÿฐ ๋’ค ์•„๋ž˜์™€ ๊ฐ™์ด CSS Code๋ฅผ ์ž…๋ ฅ ํ•ด ์ค„ ๊ฒƒ์ด์—์š”.

/pages/index.vue



/pages/index.vue


๊ทธ๋Ÿฐ ๋’ค CSS๋ฅผ ์ด์šฉํ•ด์„œ ์œ„์™€ ๊ฐ™์ด ์ž…๋ ฅ์„ ํ•ด ์ฃผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ข€ ๋” ๊น”๋”ํ•œ Page๋ฅผ ๋งŒ๋‚  ์ˆ˜ ์žˆ์–ด์š”.

 

http://localhost:4000

 

 

 

๋ฐ˜์‘ํ˜•

 

 

        ๐Ÿ“ฆ ์ƒ์„ธ ํŽ˜์ด์ง€ ๊ตฌํ˜„์„ ์œ„ํ•œ ์‚ฌ์ „ ์ž‘์—…

์ตœ์ดˆ ํ•„์š” ์—†๋Š” ๋ถ€๋ถ„์„ ์ •๋ฆฌ๋ฅผ ํ•˜๋„๋ก ํ• ๊ฒŒ์š”.

์ด์ „์— ์šฐ๋ฆฌ๋Š” `layouts` ๋ฐ‘์— `default.vue`์— ๊ณตํ†ต์ ์œผ๋กœ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋‚ด์šฉ์„ ์ถ”๊ฐ€ ํ•ด ์ค€ ๊ฒƒ์ด์—์š”.

๋ฐ”๋กœ ์œ„์™€ ๊ฐ™์€ ๋‚ด์šฉ์ด์˜€์ฃ .

์ด ๋ถ€๋ถ„์„ ์ •๋ฆฌ ํ•˜๋„๋ก ํ• ๊ฒŒ์š”.


/layouts/default.vue

์œ„์™€ ๊ฐ™์ด ์ •๋ฆฌ๋ฅผ ํ•ด ์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.


/pages/index.vue

๊ทธ๋Ÿฐ ๋’ค ์œ„ 4๋ฒˆ์งธ ์ค„์— `<h1>` Tag ๋‚ด์šฉ๊ณผ 12๋ฒˆ์งธ ์ค„ ๋‚ด์šฉ๋„ ์‚ญ์ œ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


http://localhost:4000

 

์ด๋ ‡๊ฒŒ ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌ๋ฅผ ํ•ด ๋ณด์•˜์–ด์š”.



 

 

        ๐Ÿ“ฆ Nuxt.js ๋™์  ๋ผ์šฐํŒ…

 

/pages/index.vue

์ตœ์ดˆ `index.vue`์— 9๋ฒˆ์งธ `<li>` Tag ์•ˆ์— `v-on:click`์„ ์ถ•์•ฝํ•œ `@click`์„ ์ด์šฉํ•˜์—ฌ ํ•ด๋‹น Tag์— Click Event๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด `moveToDeatailPage()`์— `product`์˜ id๊ฐ’์„ ๋„˜๊ธฐ๋„๋ก ํ•˜์˜€์–ด์š”.


/pages/index.vue


๊ทธ๋Ÿฐ ๋’ค 58 ~ 64๋ฒˆ์งธ ์ค„ ์ฒ˜๋Ÿผ `methods` ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•˜๊ณ , ๊ทธ ์•ˆ์— `moveToDetailPage()`๋ฅผ ์„ ์–ธํ•˜๊ณ , ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ id๋ฅผ ๋ฐ›๋„๋ก ํ•œ ๋‹ค์Œ Cosole๋กœ ํ•ด๋‹น ๋‚ด์šฉ์„ ์ฐ์–ด๋ณด๋„๋ก ํ•˜์˜€์–ด์š”.



http://localhost:4000

์œ„์™€ ๊ฐ™์ด `<li>` Tag ์•ˆ์— ๋‚ด์šฉ์„ ํด๋ฆญํ•˜๋ฉด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ํ•ด๋‹น ๊ฐ’์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.



/pages/index.vue

์ด๋ฒˆ์—๋Š” Nuxt.js์˜ ๋™์  ๋ผ์šฐํŒ…์„ ์ด์šฉํ•ด ๋ณผ ๊ฒƒ์ด์—์š”.

์ด์ „์— ์ฃผ๋‹ˆํ•˜๋ž‘์€ Vue.js๋ฅผ ํ†ตํ•ด Project๋ฅผ ํ•˜๋ฉด์„œ Page Re Rendering์ด ํ•„์š”ํ•˜๋ฉด Router๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , ํ•ด๋‹น Router๋ฅผ ํ†ตํ•ด ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ž‘์—…์„ ํ•ด ์ค€ ๊ฒƒ์ด์—์š”. ํ•ด๋‹น ๋‚ด์šฉ์— ๊ธฐ๋ณธ ๋‚ด์šฉ์„ ์ •๋ฆฌ๋Š” `์ด ๊ณณ`์— ์ค€๋น„ ํ•ด ๋‘์—ˆ์–ด์š”!


๊ทธ๋Ÿฐ๋ฐ, Nuxt.js๋Š” Vue.js์™€๋Š” ๋‹ฌ๋ฆฌ ์ž๋™์œผ๋กœ Router๋ฅผ ๊ด€๋ฆฌํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— 64๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ `this` Keyword๋ฅผ ์ด์šฉํ•ด Router๋ฅผ ํ˜ธ์ถœํ•œ ๋’ค `push()`์•ˆ์— ์ด๋™ํ•  ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ๋ฉด ๋๋‚˜๋Š” ๊ฒƒ์ด์—์š”.

์ฃผ๋‹ˆํ•˜๋ž‘์€ `pages` Package ๋ฐ‘์— `detail`์ด๋ผ๋Š” Package๋ฅผ ๋งŒ๋“ค์—ˆ๊ณ , ๊ทธ ๋ฐ‘์— `_id.vue`๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

/pages/detail/_id.vue

์‹ค๋ฌด์— ํˆฌ์ž…ํ•ด์„œ ๋ณด๋‹ˆ ์ด ๋‚ด์šฉ์ด ์•„์ฃผ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์œผ๋กœ ์ƒ๊ฐ๋˜์š”.

์ฃผ๋‹ˆํ•˜๋ž‘์€ /pages/index.vue์˜ 64๋ฒˆ์งธ ์ค„์— router๋ฅผ ์ด์šฉํ•˜์—ฌ `push()`์— ๋งค๊ฐœ ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ `detail/${id}`๋ฅผ ๋„ฃ์–ด์ฃผ์—ˆ์–ด์š”.

์—ฌ๊ธฐ์„œ ์ฃผ๋‹ˆํ•˜๋ž‘์€ "์•„~~~"๋ฅผ ์™ธ์น˜๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, pages ๋ฐ‘์— `push()` ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋ฌธ์ž์—ด๋กœ ์ค€ ์ธ์ž๊ฐ’์ด ๊ฒฐ๊ตญ์€ Package ์ด๋ฆ„์ด ๋  ๊ฒƒ์ด๊ณ , ๋ฆฌํ„ฐ๋Ÿด ๋ฌธ๋ฒ•์„ ์ด์šฉํ•˜์—ฌ id๊ฐ’์„ ๋„˜๊ธด๋‹ค๋ฉด ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•  Page Component๋Š” `_id.vue`๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋ฉด ๋˜๋Š” ๊ฒƒ์ด์—์š”.


์ฆ‰ Vue.js๋ฅผ ํ†ตํ•ด Page๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” `detail.vue` ๋“ฑ์˜ ์ด๋ฆ„์„ ์ •ํ•ด์ฃผ์—ˆ์ง€๋งŒ, ์ด๋ ‡๊ฒŒ ์ด๋ฆ„์ด ์ •ํ•ด์ ธ ์žˆ๋‹ค๊ณ  ๋ณด๋ฉด ๋˜๋Š” ๊ฒƒ์ด์—์š”.

์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด ๊ฒฐ๊ตญ `_`๋Š” `/`์™€ Matching์ด ๋œ๋‹ค๊ณ  ๋ณด๋ฉด ๋˜๊ณ , `{id}`๋Š” `id.vue`์™€ Matching์ด ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์•„์ฃผ ์ดํ•ด๊ฐ€ ์‰ฌ์šด ๊ฒƒ์ด์—์š”.

์œ„์™€ ๊ฐ™์ด Coding์„ ํ•˜๊ณ  ์‹ค์ œ ํ•ด๋‹น ๋‚ด์šฉ์„ ํด๋ฆญํ•ด ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณ€ํ™”๊ฐ€ ์ƒ๊ฒจ์š”.


http://localhost:4000


์ตœ์ดˆ ์œ„์™€ ๊ฐ™์ด main Page๊ฐ€ ์—ด๋ฆฌ๊ฒŒ ๋˜์—ˆ์„ ๋•Œ, ์œ„์—์„œ ์˜ค๋ฅธ์ชฝ์œผ๋กœ 3๋ฒˆ์งธ ๊ทธ๋ฆผ์„ ํด๋ฆญํ•ด ๋ณผ๊ฒŒ์š”.

 

http://localhost:4000/detail/$%7Bid%7D


๊ทธ๋Ÿผ ์œ„์™€ ๊ฐ™์ด ์ƒ์„ธ ํŽ˜์ด์ง€๋ผ๊ณ  ํ•ด์„œ `/pages/detail/_id.vue`๋กœ ๋งŒ๋“  Page๋กœ ์ด๋™์„ ํ•˜๊ฒŒ ๋˜๊ณ , ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ†ตํ•ด Console.log๋กœ ์ฐํžŒ ๋งˆ์ง€๋ง‰ ๋‚ด์šฉ์„ ๋ณด๊ฒŒ ๋˜๋ฉด `route`์— ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.


์ด๋ฒˆ์—๋Š” `axios`๋ฅผ ๋ณด๋‹ค ๊น”๋”ํ•˜๊ฒŒ ์ด์šฉํ•ด ๋ณด๋„๋ก ํ• ๊ฒŒ์š”.

๋จผ์ € Project ์ตœ์ƒ์œ„ Packag์— `api` Package๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์„ธ์š”.

๊ทธ๋Ÿฐ ๋‹ค์Œ ์•„๋ž˜์™€ ๊ฐ™์ด `index.js`๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์„ธ์š”.

 

/api/index.js

 

 

/api/index.js

 

๋”ฑ ๋ณด๋ฉด ์•„์‹œ๊ฒ ์ง€๋งŒ, ์ด ๊ณณ์€ Back End์—๊ฒŒ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด์—์š”.

ํ˜„์žฌ Back End์˜ port ๋ฒˆํ˜ธ๋Š” 3000์ด๊ณ , Front End ์ฆ‰, Nuxt.js์˜ Port ๋ฒˆํ˜ธ๋Š” 4000์œผ๋กœ ์„ค์ •์ด ๋˜์–ด ์žˆ์–ด์š”.

๋จผ์ € 3๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ Instance ์ƒ์ˆ˜ํ˜• ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š”๋ฐ, `axios`์˜ `create()`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ `baseURL` ๊ฐ์ฒด์— Back End ์ฃผ์†Œ์™€ Port ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋‹ค์Œ 7๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ `fetchProductById()`๋ฅผ ๋งŒ๋“  ๋’ค id๋ฅผ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋ฐ›๊ฒŒ ํ•œ ๋‹ค์Œ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์œ„์—์„œ ๋งŒ๋“  instance ์ƒ์ˆ˜ํ˜• ๋ณ€์ˆ˜ ์•ˆ์— `get()`(HTTP Method - get)์„ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ๊ทธ ๊ณณ์— Back End Server์— ํ˜ธ์ถœํ•  API URI๋ฅผ ์ ์€ ๋’ค Parameter ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

13๋ฒˆ์งธ ์ค„์€ ์–ด๋Š ๊ณณ์—์„œ๋‚˜ importํ•ด์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ ์–ธํ•œ ๊ฒƒ์ด์—์š”.



/pages/detail/_id.vue


์ด๋ฒˆ์—๋Š” `_id.vue`์—์„œ ์ตœ์ดˆ `fetchProductById`๋ฅผ 14๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ import๋ฅผ ํ•ด ์ฃผ๊ณ , ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด `asyncData()`๋ฅผ ํ†ตํ•ด Page๊ฐ€ ๊ทธ๋ ค์ง€๊ธฐ ์ „์— Back End์—์„œ Data๋ฅผ ๋ฐ›์•„์˜ค๊ฒŒ ํ•ด ์ค„ ๊ฒƒ์ด์—์š”.

20๋ฒˆ์งธ ์ค„์— `fetchProductById()`์— `parma.id`๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด Back End์—์„œ Data๋ฅผ ๋ฐ›์•„ ์ƒ์ˆ˜ํ˜• ๋ณ€์ˆ˜ `response`์— ๋ฐ›์€ ๋’ค ์•ˆ์— ๋‚ด์šฉ์„ ๋‹ค์‹œ ์ƒ์ˆ˜ ํ˜• ๋ณ€์ˆ˜ `product`์— ๋„ฃ์–ด ์ฃผ์—ˆ๊ณ , ๊ทธ ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ ํ•ด ์ฃผ์—ˆ์–ด์š”.

`asyncData()`์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ž…๋ ฅ๋œ `{ parmas }`๋Š” ๋’ค์—์„œ ์ข€ ๋” ๊ณต๋ถ€ํ•ด ๋ณด๋„๋ก ํ• ๊ฒŒ์š”.

๊ทธ๋Ÿฐ ๋’ค 6 ~ 8๋ฒˆ์งธ ์ฒ˜๋Ÿผ Back End์—์„œ ๋ฐ›์•„์˜จ Data๋ฅผ ๋ฟŒ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด HTML Tag๋ฅผ ํ†ตํ•ด ์ž‘์—…์„ ํ•ด ์ฃผ์—ˆ์–ด์š”.


http://localhost:4000


์ตœ์ดˆ Main Page์˜ ๋ชจ์Šต์ด์—์š”. ์ด ๊ณณ์—์„œ ๋งจ ์œ„์˜ ์˜ค๋ฅธ์ชฝ ์ฒซ๋ฒˆ์งธ ์‚ฌ์ง„์„ ๋ˆŒ๋Ÿฌ ๋ณผ๊ฒŒ์š”.



http://localhost:4000/detail/2


์šฐ์™€! ๐Ÿ˜ƒ

์ด๋ ‡๊ฒŒ Back End์—์„œ ๋ถˆ๋Ÿฌ์˜จ Data๋ฅผ ์˜ˆ์˜๊ฒŒ ๊ทธ๋ ค์ฃผ์—ˆ์–ด์š”.

 

 

 

 



 

 

        ๐Ÿ“ฆ Context ์†์„ฑ

์ด๋ฒˆ์—๋Š” `asnyncData()`์˜ `Context` ์†์„ฑ์— ๋Œ€ํ•ด ๊ณต๋ถ€ ํ•ด ๋ณผ๊ฒŒ์š”.
`asnyncData()`์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜(Parameter)๋Š” `Context` ์ธ ๊ฒƒ์ด์—์š”. ์ปจํ…์ŠคํŠธ ์†์„ฑ์€ Nuxt.js Framework ์ „๋ฐ˜์— ๊ฑธ์ณ ๊ณต์šฉ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์†์„ฑ์œผ๋กœ Plug In, Middleware ๋“ฑ์˜ ์†์„ฑ์—์„œ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์š”.

์ปจํ…์ŠคํŠธ์—๋Š” Store, Router ๊ด€๋ จ ์ •๋ณด๋ฟ ์•„๋‹ˆ๋ผ SSR ์š”์ฒญ, ์‘๋‹ต ๊ด€๋ จ๋œ ์†์„ฑ๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ

function (context) { // asyncData, plugins, middleware, ...
  // Always available
  const {
    app,
    store,
    route,
    params,
    query,
    env,
    isDev,
    isHMR,
    redirect,
    error,
   $config
  } = context

  // Only available on the Server-side
  if (process.server) {
    const { req, res, beforeNuxtRender } = context
  }

  // Only available on the Client-side
  if (process.client) {
    const { from, nuxtState } = context
  }
}


์˜ˆ์ œ ์ฝ”๋“œ ๋งจ ์œ„์— `function`๊ณผ `(context)` ์‚ฌ์ด์—๋Š” `asnyncData()`๊ฐ€ ์ƒ๋žต๋˜์–ด ํ‘œ๊ธฐ ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด์•ผ ํ•ด์š”.
์ด๋ ‡๊ฒŒ ํ‘œ๊ธฐํ•˜๋Š” ๊ฒƒ์„ `ES6+ destructuring` ๋ฌธ๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ต๋‹ˆ๋‹ค. ์ด ๋ฌธ๋ฒ•์€ ๊ฐ์ฒด์— ์†์„ฑ์— ๋ฐ”๋กœ ์ ‘๊ทผํ•˜๋Š” ๋ฌธ๋ฒ•์ด์—์š”.

`asnyncData()`๋Š” ์–ด๋–ป๊ฒŒ Error๋ฅผ ์ฒ˜๋ฆฌํ• ๊นŒ์š”?

์˜ˆ์ œ ์ฝ”๋“œ

export default {
  async asyncData({ params, $http, error }) {
    try {
      const response = await axios.get(`/users/${params.id}`);
      const user = response.data;
      return { user }
    } catch(e) {
      error({ statusCode: 503, message: 'API ์š”์ฒญ์ด ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค ๋‹ค์‹œ ์‹œ๋„ํ•ด ์ฃผ์„ธ์š”' })
    }
  }
}


์ด๋ฒˆ์—๋Š” ์œ„์— ๋‚ด์šฉ์„ ๊ฐ€์ง€๊ณ , `/pages/detail/_id.vue`์— ์ž‘์—…์„ ํ•ด ๋ณผ๊ฒŒ์š”.

๋จผ์ € ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •์„ ํ•ด ์ฃผ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

/pages/detail/_id.vue


์ฐธ๊ณ ๋กœ CSS์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์œ„์น˜ํ•ด ์žˆ์œผ๋‹ˆ ํ•„์š”ํ•˜์‹  ๋ถ„๋“ค์€ ์ฃผ๋‹ˆํ•˜๋ž‘์˜ Git Hub์—์„œ ๋‚ด๋ ค ๋ฐ›๊ธฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 

/pages/detail/_id.vue

CSS๋Š” ์œ„์™€ ๊ฐ™์ด ์„ค์ •์„ ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์œ„์™€ ๊ฐ™์ด ์ƒ์„ธ ํŽ˜์ด์ง€๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”!

 

 

์œ„์™€ ๊ฐ™์ด ํ•ด ๋‘๊ฒŒ ๋˜๋ฉด ๋ถ„๋ช… ์œ„์™€ ๊ฐ™์ด Error๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ธ๋ฐ, ๊ทธ ์ด์œ ๋Š” `<button>` Tag์—์„œ `@click` Event๋กœ ์ด๋™ํ•  Method๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.

์ด ๋ถ€๋ถ„์„ ์ž ์‹œ ์ฃผ์„์ฒ˜๋ฆฌ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

/pages/detail/_id.vue - 15๋ฒˆ์งธ ์ค„ ์ฃผ์„ ์ฒ˜๋ฆฌ

 

์ž ๊น! ์ฃผ๋‹ˆํ•˜๋ž‘์ด CSS ๊ด€๋ จํ•ด์„œ Git Hub ์—์„œ ๋‚ด๋ ค๋ฐ›๊ธฐ๋ฅผ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค๊ณ  ๋ง์”€ ๋“œ๋ ธ๋Š”๋ฐ, ํ•ด๋‹น File์€ Nuxt.js Project์—์„œ Global(์ „์—ญ)์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์„ค์ •์„ ํ•ด ์ฃผ์–ด์•ผ ํ•ด์š”.

๋จผ์ € `nuxt.config.js`์— ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •์„ ํ•ด์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

/nuxt.config.js

 

 

18๋ฒˆ์งธ ์ค„์ฒ˜๋Ÿผ Global css ์„ค์ • ๋ถ€๋ถ„์ด ์žˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์— css๊ฐ€ ์œ„์น˜ํ•œ ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅ ํ•ด ์ฃผ๋ฉด ๋˜๋Š”๊ฒƒ์ด์—์š”.


๋‹ค์Œ๋ฒˆ ๋‚ด์šฉ์€ '์‡ผํ•‘ ์ƒํ’ˆ ๊ฒ€์ƒ‰ UI'๋ฅผ ํ•œ๋ฒˆ ๊ฐœ๋ฐœํ•ด ๋ณด๋ฉด์„œ ๊ณต๋ถ€๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•ด์š”.

 

 

 

 

 

 

ํ•œ ๊ถŒ์œผ๋กœ ๋ฐฐ์šฐ๋Š” Vue js 3 ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ๊ธฐ์ดˆ ์‹ค์ „ (์˜์ง„์ฑ…)

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•