[Nuxt.js] ๋น๋๊ธฐ ๋ฐ์ดํฐ ํธ์ถ ๋ฐฉ๋ฒ
2022. 5. 22. 02:17ใFront-End ์์ ์ค/Nuxt.js
728x90
๋ฐ์ํ
๐ Nuxt.js ๋น๋๊ธฐ ๋ฐ์ดํฐ
๐ฝ ํธ์ถ ๋ฐฉ๋ฒ
๐ฆ ๊ฐ์
Nuxt.js๋ SSR(Server Side Rendering) Framework๋ก Vue.js Single Paga Application๊ณผ `REST API` ํธ์ถ ๋ฐฉ์์ ๋ค๋ฅด๊ฒ ์ ๊ทผํด์ผ ํฉ๋๋ค.
๐ฆ Single Page Application๊ณผ์ ์ฐจ์ด์
CSR(Client Side Rendering)์ธ Vue Single Page Application Data ํธ์ถ ๋ฐฉ์์ ์๋์ ๊ฐ์ต๋๋ค.
<!-- UserProfile.vue -->
<template>
<div>
<p>{{ user }}</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
user: {},
}
},
methods: {
async fetchUser() {
const response = await axios.get('/users/1');
this.user = response.data;
}
},
created() {
this.fetchUser();
},
}
</script>
`Created()` Life Cycle Hook์ ์ด์ฉํด Component๊ฐ ์์ฑ๋๋ฉด Server์ Data๋ฅผ ์์ฒญํด ๋ฐ์์จ ๊ฒฐ๊ณผ๋ฅผ ํ๋ฉด์ ํ์ํ๋ Code์์. ์ด๋ Server์ Data๋ฅผ ์์ฒญํ๋ ์์ ์ ๋ธ๋ผ์ฐ์ ์์ Vue.js Code๊ฐ ํ๋ฉด์ `DOM`์ ๊ตฌ์ฑํ๊ณ , Script๋ฅผ ์คํํ๋ ์์ ์ธ ๊ฒ์ด์์. `Client Side Rendering๊ณผ ServerSide Rendering ์ฐจ์ด์ `์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด
Client Side Rendering์ ๋น ํ๋ฉด์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐ์ ํ๋ฉด์ ๋ฟ๋ฆด ์์์ Data๋ฅผ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ๊ตฌ์ฑํ๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ code๊ฐ ๊ฐ๋ฅํด์.
ํ์ง๋ง Nuxt.js๋ Server์์ Page ๋ด์ฉ์ ๋ชจ๋ ๊ทธ๋ ค ๋ธ๋ผ์ฐ์ ๋ก ๊ฐ์ ธ๊ฐ์ผ ํ๋๋ฐ, ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
๐ฆ REST API ํธ์ถ ๋ฐฉ์
์์์ ๋ณธ ๊ฒ์ฒ๋ผ ์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์
์์ ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๊ธฐ ์ํด `Vue Lift Cycle Hook`์ ์ด์ฉ ํ ๊ฒ์ด์์. Nuxt.js์์๋ ์๋ 2๊ฐ์ง ์ธ์คํด์ค ์ต์
์์ฑ์ด ๋ณ๋ ์ ๊ณต๋ฉ๋๋ค.
โ acnycData
`acyncData`๋ Page Component(pages Package ์๋ ์์นํ๋ Component)์๋ง ์ ๊ณต๋๋ ์์ฑ ์
๋๋ค. `asyncData`๋ก ์๋์ ๊ฐ์ด Server์๊ฒ Data๋ฅผ ์์ฒญํ ์ ์์ด์.
์์ ์ฝ๋
<!-- pages/user.vue -->
<template>
<div>
<p>{{ user }}</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
// params์ id๊ฐ 1์ด๋ผ๊ณ ๊ฐ์
async asyncData({ params, $http }) {
const response = await axios.get(`/users/${params.id}`);
const user = response.data;
return { user }
}
}
</script>
๋ฐ์ํ
์ codesms URL `/user`๋ก ์ ๊ทผํ ๋ `user.vue` Component๋ฅผ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ธฐ ์ ์ Data๋ฅผ ์์ฒญํ๋ Code์์.
Data๋ฅผ ๋ค ๋ฐ์์์ผ์ง๋ง Data๋ฅผ ๋ค๊ณ `<template></template>` ์์ญ์ Code๋ฅผ ํ๋ฉด์ ํ์ํฉ๋๋ค. ๋ง์น ์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์
์ ๋ทฐ ๋ผ์ฐํฐ์์ ๋ค๋น๊ฒ์ด์
๊ฐ๋์์ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ๊ณ , ๋ฐ์์์ ๋ ํ์ด์ง๋ฅผ ์ง์
ํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
- asyncData Parameter
`asyncData` ์์ฑ์ ํ๋ผ๋ฏธํฐ๋ `context` ์์ฑ์ธ ๊ฒ์ด์์. Context ์์ฑ์ Nuxt.js ์ ๋ฐ์ ๊ฑธ์ณ ๊ณต์ฉ์ผ๋ก ์ฌ์ฉ๋๋ ์์ฑ์ผ๋ก Plug In, Middleware ์์ฑ์์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค. Context์๋ Store, Roeuter ๊ด๋ จ ์ ๋ณด๋ฟ๋ง ์๋๋ผ, 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
}
}
- asyncData Error Code
`acyncData` ์์ฑ์์ API ํธ์ถ Error๊ฐ ๋ฐ์ํ์ ๋๋ ์๋์ ๊ฐ์ด Error Page๋ก ์ด๋์ํฌ ์๋ ์์ด์.
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 ์์ฒญ์ด ์คํจํ์ต๋๋ค ๋ค์ ์๋ํด ์ฃผ์ธ์' })
}
}
}
โ fetch
`fetch`๋ Page Component ๋ถ ์๋๋ผ ์ผ๋ฐ Vue Component์์๋ ์ด์ฉํ ์ ์๋ Data ํธ์ถ ์์ฑ์ธ ๊ฒ์ด์์. ๋ค์ 2๊ฐ์ง ์ํฉ์์ ํธ์ถ์ด ๋๋ต๋๋ค.
โฆ SSR(Server Side Rendering)์ ์ํด Server์์ ํ๋ฉด์ ๊ตฌ์ฑํ ๋ Component๊ฐ ์์ฑ๋๊ณ ๋์ ์คํ.
โฆ ๋ธ๋ผ์ฐ์ ์์ URL ์ฃผ์๋ฅผ ๋ณ๊ฒฝํด์ Page ์ด๋ํ ๋.
์์ ์ฝ๋
<!-- components/UserProfile.vue -->
<template>
<div>{{ user }}</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
user: {},
}
},
async fetch() {
const res = await axios.get('https://jsonplaceholder.typicode.com/users/1');
this.user = res.data;
},
}
</script>
๋ง์ฝ ์ Component๊ฐ ์๋์ ๊ฐ์ด main.vue Component์ ๋ฑ๋ก ๋์ด ์๊ณ , URL ์ฃผ์๊ฐ `/` ์์ `/main`์ผ๋ก ๋ณ๊ฒฝ๋๋ฉด Component๊ฐ ํ๋ฉด์ ๋ถ์ฐฉ๋๊ณ ๋์(mounted) `fetch`์์ Data Call Logic์ด ์คํ๋ฉ๋๋ค.
<!-- pages/main.vue -->
<template>
<div>
<h1>๋ฉ์ธ ํ์ด์ง</h1>
<UserProfile></UserProfile>
</div>
</template>
<script>
import UserProfile from '@/components/UserProfile.vue'
export default {
components: {
UserProfile,
},
}
</script>
์ ๋์์์ ๋ณผ ์ ์๋ฏ ์ต์ด `/`๋ก ์ ๊ทผํ๊ณ , `/main`์ผ๋ก ์ด๋์ ํ๊ธฐ์ Component๊ฐ ํ๋ฉด์ ๋จผ์ ๋ฟ๋ ค์ง๊ณ ๋์ fetch ํธ์ถ์ด ์คํ๋ฉ๋๋ค. ์ด ๋๋ฌธ์ `/main`์ผ๋ก ์ด๋ํ๊ณ ๋๋ฉด Data๋ฅผ ๋ฐ์์ค๋ ๋์ `user` ์์ฑ์ ๊ธฐ๋ณธ ๊ฐ์ธ `{}`๊ฐ ๋จผ์ ํ๋ฉด์ ๋ณด์ด๊ณ ์ ์ ๋ค ๋ฐ์์จ Data๊ฐ ํ๋ฉด์ ๋ฟ๋ ค์ง๋ ๊ฒ์ ๋ณผ ์ ์์ด์.
์ฌ๊ธฐ์ ๋ง์ฝ ์ต์ด Web Service๋ฅผ `/main`์ผ๋ก ์ ๊ทผํ๊ฒ ๋๋ฉด Server ํ๋ฉด์ ๊ตฌ์ฑํ ๋ ํธ์ถ ๋๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํ๋ฉด์ Data๊ฐ ํธ์ถ๋ ์ํ๋ก Page๊ฐ ๋ํ๋๊ฒ ๋ ๊ฒ์ด์์.
- fetch ํน์ง
fetch๋ asyncData์ ๋ค๋ฅด๊ฒ ์๋์ ๊ฐ์ ์์ฑ๋ค์ด ์ ๊ณต๋ฉ๋๋ค.
โฆ $fetchState : Data ํธ์ถ ์ํ๋ฅผ ๋ํ๋ด๋ ์์ฑ์ผ๋ก ์ธ์คํด์ค๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ฉฐ ํธ์ถ ์ํ์ ๋ฐ๋ผ `pending`, `error`, `timestamp` ์ ๊ณต.
โฆ $fetch : fetch Logic์ ๋ค์ ์คํ์ํฌ ์ ์๋ ํจ์.
โฆ fetchOnServer : SSR์์ Server์์ `fetch`๋ฅผ ์คํํ ์ง ๋ง์ง ๊ฒฐ์ ํ๋ ์์ฑ์ผ๋ก ๊ธฐ๋ณธ๊ฐ์ `true`.
์์ ์ฝ๋
<template>
<div>
<article>
<p v-if="$fetchState.pending">์ฌ์ฉ์ API ํธ์ถ ์ค</p>
<p v-else-if="$fetchState.error">์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค</p>
<div v-else>{{ user }}</div>
</article>
<button @click="fetchUser">๋ค์ ํธ์ถํ๊ธฐ</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
user: {},
}
},
methods: {
fetchUser() {
// fetch ์์ฑ์ ๋ก์ง์ ์คํํฉ๋๋ค.
this.$fetch();
}
},
async fetch() {
const res = await axios.get('https://jsonplaceholder.typicode.com/users/1');
this.user = res.data;
},
// ์๋ ์์ฑ์ 'false'๋ก ๋ฐ๊พธ๋ฉด ์๋ฒ์์ ํ๋ฉด์ ๊ตฌ์ฑํ ๋ `fetch` ์์ฑ์ ๋ก์ง์ด ์คํ๋์ง ์์ต๋๋ค.
fetchOnServer: false
}
</script>
728x90
๋ฐ์ํ
'Front-End ์์ ์ค > Nuxt.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์ฉํ์ฌ ์ผํ ์ํ ๊ฒ์ UI ๊ฐ๋ฐ (0) | 2022.06.01 |
---|---|
[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์ฉํ์ฌ ์ผํ ์ํ ๋ชฉ๋ก ํ์ด์ง์ ์์ธ ํ์ด์ง ๊ฐ๋ฐ (0) | 2022.05.24 |
[Vue+Nuxt.js] Nuxt.js Data ํธ์ถ ๋ฐฉ์๊ณผ API ์ฐ๋ (0) | 2022.05.22 |
[Vue+Nuxt.js] Nuxt.js ์์ํ๊ธฐ (0) | 2022.05.18 |
[Vue+Nuxt.js] Nuxt.js ๊ธฐ๋ณธ (0) | 2022.05.17 |