๐ฒ๋์ ๋ ์ด์์์ด ์๋ VueJS ํ์ด์ง!๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ์!
18920 ๋จ์ด webdevvuejavascriptbeginners
์ฐ๋ฆฌ๋ ๋ ๊ฐ์ ๋ฐฐ์น๋ถํฐ ์์ํ๋ค.ํ๋์ ๋ ์ด์์์ ๋ก๊ทธ์ธ์ด๋ ๋ฑ๋ก ํผ์ด ์๋ ํจํด ๋ ์ด์์์ด๋ค.๋ฐ๋ผ์ ๋ฐฐ์น์ ๋ชจ๋ ์ปจํ ํธ๋ ํ์ด์ง์ ์์ง ๋ฐ ์ํ ์ค์ฌ์ ์์ต๋๋ค.์ฐ๋ฆฌ์ ๋ ๋ฒ์งธ ํฌ์์ ์ ํ์ ์ธ ์์ฉ ํฌ์์ด๋ค.์ด ๋ ์ด์์์๋ ํ์ ๋ฉ๋ด, ์๋ฆผ, ๊ฒ์ ๋ฑ์ ๊ตฌ์ฑ ์์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
๋ํ VueX ๋ฐ Axios๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฑ์๋์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.์ฐ๋ฆฌ๋ ๋๊ตฌ๋ฅผ ์์์ ์๋๋ก ์ ๋ฌํ๊ฑฐ๋ ๋ค๋ฅธ ๋ฐฉํฅ์ผ๋ก ์ ๋ฌํ ํ์๊ฐ ์๋ค.๋ง์ฝ ํ์ํ๋ค๋ฉด, ์ฐ๋ฆฌ๋ ๋ฐฑ์๋ ๋ฐ์ดํฐ์ ๋ฐฉ๋ฒ์ ๋ชจ๋ธ๋งํ๋ ์ ์ฅ์๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์ด์ ์ฌ์ฉ๋ ๊ธฐ์ ์ ๋ํด ์ ์๊ณ ๊ณ์๊ธฐ ๋๋ฌธ์ VueJS์์ ํํ ๋ณผ ์ ์๋ ๋์ ๋ ์ด์์ ์๋ฃจ์ ์ ๋ฌธ์ ์ ์ ํ ๋ก ํ๊ฒ ์ต๋๋ค.
๊ฐ๋จํ ์๊ฐ
์ฝ๋ ์์์ ๋ํด ๋๋ 3๊ฐ
vue cli
ํญ๋ชฉ์ ๋ง๋ค์๋ค.๊ทธ๊ฒ๋ค์ ๋ชจ๋
main.js
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋ ์ธ๊ทธ๋จผํธ๋ฅผ ์ถ๊ฐํ๋ค.Vue.mixin({
created() {
console.log('[created] ' + this.$options.name)
},
});
์ด๊ฒ์ ๊ตฌ์ฑ ์์๋ฅผ ์์ฑํ ๋๋ง๋ค conols.log()
๊ตฌ์ฑ ์์ ์ด๋ฆ์ ํ์ํฉ๋๋ค.VueJS ์ด์
๋ธ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ฝ๊ฒ ๋ณผ ์ ์์ต๋๋ค.mounted()
์ detroyed()
์ฐ๊ฒฐ๋ ์ถ๊ฐํ ์ ์๋ค.์ฐ๋ฆฌ์ ์คํcreated()
์ผ๋ก๋ ์ถฉ๋ถํ๋ค.์ง๋ฌธ 1: ๋ ธ์ ๋ณ๊ฒฝ ์ ์ฌ์ ์ฐฐ
์ธํฐ๋ท์์ ๋์ ๋ ์ด์์์ ๊ฒ์ํ ๋, ๋น์ ์ ๋ง์ ํด๊ฒฐ ๋ฐฉ์์ ๋ฐ๊ฒฌํ ์ ์๋๋ฐ, ๊ทธ ์ค์์ ๊ฐ์ฅ ํํ ๋ณผ ์ ์๋ ๊ฒ์ ์๋์ ํ๋์ด๋ค.
App.vue
์๋ ๋ค์ ์ฝ๋๊ฐ ์์ต๋๋ค.<template>
<div id="app">
<router-view/>
</div>
</template>
๊ทธ๋ฆฌ๊ณ ๋ชจ๋ ํ์ด์ง/๋ณด๊ธฐ์ ์ด๋ค ๋ ์ด์์์ด ์์ด์ผ ํ๋์ง ์๋ ค ์ค๋๋ค.๊ทธ๊ฒ์ ๋ณดํต ์๋About.vue
๊ตฌ์ฑ ์์์ฒ๋ผ ๋ณด์ธ๋ค.<template>
<LayoutB>
<div class="about">
<h1>This is an about page</h1>
</div>
</LayoutB>
</template>
<script>
import LayoutB from "../layouts/LayoutB";
export default {
name: "About",
components: {
LayoutB
}
};
</script>
์ด๊ฒ์ ์์ฉ์ ํ ๋ฟ๋ง ์๋๋ผ, ์ฐ๋ฆฌ๋ ์ด ๋ฐฉ๋ฉด์์ ๋ง์ด ํ์ง ์๊ธฐ ๋๋ฌธ์, ์คํผ๋ ๋จธ์ ์ ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์๋ค๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ง ๋ชปํ ๊ฒ์ด๋ค.๊ทธ๋ผ ๋ฌธ์ ๋ ๋ญ๊น์?์ด๋ฅผ ์ํด ์์
Vue.Mixin()
์กฐ์ ํจ์๋ฅผ ์ดํด๋ณด์.console.log
๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.ํ์ด์ง๋ฅผ ๋ถ๋ฌ์ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฐฝ์ค ์์๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
'App (entry point)' -> 'Home (view/page)' -> 'LayoutA (layout)' -> 'Components'
๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์ง๊ธ ๊ตฌ์ฑ ์์๋ฅผ ์ด๋ป๊ฒ ์ค์ ํ๋์ง ๋ณธ๋ค๋ฉด, ์ด๊ฒ์ ์ ํํ๋ค.๋ ์ด์์ ์ ์ ํ์ด์ง๋ฅผ ๋ถ๋ฌ์ค๋ ๊ฒ์ ๋ฌธ์ ๊ฐ ๋ ์ ์์ง๋ง ์ฑ๋ฅ์ ํฐ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.๋ ํฐ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ ์ฒด ๋ ์ด์์์ ํ๊ดดํ๊ณ ๋ค์ ๋ง๋ค๊ณ ์์ต๋๋ค.์ด๊ฒ์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค/์ฌ์ฉ์ ์ฒดํ์ ๋ฆ์ถ๊ณ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ฅผ ๋ถ๋ฆฌํ๋ ๋ชฉ์ ์ ํ๊ดดํ ๊ฒ์ด๋ค.๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ ํ๊ดดํ๊ณ ์ฐฝ์กฐํ๋ค๋ฉด, ์ค๋ น ์ฐ๋ฆฌ๊ฐ ์ด๋ ๊ฒ ํ ํ์๊ฐ ์๋ค ํ๋๋ผ๋.
๋ง์ฝ ์๋ฆผ ์์คํ ์ด ์๋ค๋ฉด, ํ์ด์ง๋ฅผ ๋ณ๊ฒฝํ ๋๋ง๋ค ํ์ง๊ธฐ๋ฅผ ๋ง๋ค ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ํฉ์ ๋์ฑ ๋๋น ์ง ๊ฒ์ ๋๋ค.
์ด ํด๊ฒฐ ๋ฐฉ์์ ์ด๋ ์ ๋ ๊ฐ๋ฅํ๋ค๊ณ ํด๋ ๋ง์กฑ์ค๋ฝ์ง ์๋ค.
์ง๋ฌธ 2: ๋์ผ ๋ ๋๋ง
์ด๊ฒ์ ์๋ง๋ ๋ด๊ฐ ๋ช ๊ฐ์ ๊ฐ์ข์ ๋ต์์์ ์ฐพ์ ๊ฐ์ฅ ์ ํํ๋ ํด๊ฒฐ ๋ฐฉ์์ผ ๊ฒ์ด๋ค.
App.vue
์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค.<template>
<div id="app">
<component :is="layout">
<router-view :layout.sync="layout" />
</component>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
layout: "div"
};
}
};
</script>
์ฐ๋ฆฌ About.vue
๋ถํฐ ์๋ ์ฝ๋๊น์ง<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<script>
import LayoutB from "../layouts/LayoutB";
export default {
name: "About",
created() {
this.$emit("update:layout", LayoutB);
}
};
</script>
์ฌ๊ธฐ์ ๊ฐ์ฅ ์ค์ํ ๋ณํ๋ sync
์$emit
๊ธฐ๋ฅ์ด๋ค.ํ์ฌ ์ฐ๋ฆฌ๊ฐ ํ๊ณ ์๋ ๊ฒ์ ๋ ์ด์์ App.vue
๊ตฌ์ฑ ์์๋ฅผ ์ฎ๊ธฐ๋ ๊ฒ์
๋๋ค. ๋ณด๊ธฐ/ํ์ด์ง ๊ตฌ์ฑ ์์๋ App.vue
๋ถ๋ฌ์ฌ ๋ ์ด์์์ ์๋ ค ์ค๋๋ค.๋ง์ฐฌ๊ฐ์ง๋ก ๋ธ๋ผ์ฐ์ ๋ง ๋ณด๋ฉด ์ด ํด๊ฒฐ ๋ฐฉ์์ด ์ ํจํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค!์ด์ ์ฐ๋ฆฌ
console.log()
์ถ๋ ฅ์ ๋ด
์๋ค.App (entry point) -> 'Home (view/page)' -> 'LayoutA (layout)' -> 'Components' -> 'Home (view/page) again๐ฑ -> Click on Contact link ->'Contact (view/page)
์ฐ๋ฆฌ๋ ๋ฌธ์ ๋ฅผ ํ๋ ํด๊ฒฐํ๋ค.ํ์ฌ, ํฌ์์ ๋งค๋ฒ ๋ ธ์ ์ด ๋ฐ๋ ๋๋ง๋ค ํ๊ดด๋๊ณ ์ฌ์ฐฝ์ค๋์ง ์์ง๋ง, ์ฐ๋ฆฌ๋ ์๋ก์ด ๋ฌธ์ ๋ฅผ ๋ง๋ค์๋ค!
์ ๋ฐฐ์น๊ฐ ํ์๋ ๋๋ง๋ค ํ์ด์ง/๋ทฐ๊ฐ ์์ฑ๋๊ณ ์ ๊ฑฐ๋ ๋ค์ ๋ค์ ์์ฑ๋ฉ๋๋ค.์ด๊ฒ์ ์ฐ๋ฆฌ ์์ ์ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์๋ค.
๊ตฌ์ฑ ์์์
fetch()
ํจ์๊ฐ ๋ชฉ๋ก์ ๋ถ๋ฌ์ฌ ๋, ์ด fetch()
ํจ์๋ ํ ๋ฒ์ด ์๋๋ผ ํ ์๋ฒ๋ฅผ ๋ ๋ฒ ๋ถ๋ฌ์ต๋๋ค.์ง๊ธ ์์ํด ๋ณด์ธ์. ๋ฐฑ์๋์ ์บ์๊ฐ ์์ต๋๋ค. ๋ณต์กํ ๊ณ์ฐ์ด ๋ ๋ฒ ์คํ๋๊ณ ์์ต๋๋ค.๋ํ ์์ ์์ ์ค๋ณต๋ ๋ฐ์ดํฐ๋ฅผ ์ป์๋์ง ํ์ธํ์ง ์์ผ๋ฉด ๋ชฉ๋ก์์ ๋ชจ๋ ๋ด์ฉ์ ๋ ๋ฒ ๋ณผ ์ ์์ต๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก ์ฐ๋ฆฌ์ ์์์์
Home
๋ LayoutA
์ด์ ์ ๋ํ๋ฌ๋ค.์ด๊ฒ์ ๋จ์ง ์ด ํด๊ฒฐ ๋ฐฉ์์ ๋ํ๋ ์ ์๋ ๋ฌธ์ ์ผ ๋ฟ์ด๋ค.
์ด๋ฐ ๋ฐฉ๋ฒ๋ ์ฐ๋ฆฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์๋๋ค.
ํด๊ฒฐ ๋ฐฉ์: ์ฐ๋ฆฌ์ ๋ ธ์ ์์ ์ ๋์์ ์ฌ์ฉํ๋ค
์ฐ๋ฆฌ๋ ๋ค์ ํ ๋ฒ ๋ฐ๊ฟ์ผ ํ๋ค
App.vue
.<template>
<div id="app">
<component :is="this.$route.meta.layout || 'div'">
<router-view />
</component>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
์ฐ๋ฆฌ About.vue
์ง๊ธ ์ด๋ ๊ฒ ๋ณด์ฌ์.<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<script>
export default {
name: "About"
};
</script>
๊ทธ๋์ ํ์ด์ง๊ฐ ์ด๋ค ๋ ์ด์์์ ๋ณด์ฌ์ค์ง ๋ชจ๋ฅธ๋ค.๊ทธ๋ฌ๋ ์ด ์ ๋ณด๋ ํ์ฌ ์ด๋์ ์ ์ฅ๋ฉ๋๊น?
์ฐ๋ฆฌ
router/index.js
ํ์ผ์์!import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import Contact from '../views/Contact.vue'
import LayoutA from '../layouts/LayoutA.vue'
import LayoutB from '../layouts/LayoutB.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { layout: LayoutA }
},
{
path: '/about',
name: 'About',
component: About,
meta: { layout: LayoutB }
},
{
path: '/contact',
name: 'contact',
component: Contact,
meta: { layout: LayoutA }
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
๊ฐ ๋
ธ์ ์ ์ ์์์ ์ฌ๊ธฐ์ ๊ฐ์ฅ ์ค์ํ ์ค์ meta: { layout: LayoutA }
์ด๋ค.์ฐ๋ฆฌ
console.log()
์ถ๋ ฅ์ ๋ค์ ๋ด
์๋ค.App (entry point) -> LayoutA (layout) -> Components from the Layout -> Home (view/page)
๊ด์ฐฎ์ ๋ณด์ฌ์.์ฐ๋ฆฌ๋ ๋ง์นจ๋ด ์ด์ค ๊ณผ์ฅ์ด ์๋ ์ ํํ ์์๊ฐ ์๊ฒผ๋ค.๋ํ ๋ ธ์ ์ ๋ณ๊ฒฝํ์ง ์์๋ ๋ ์ด์์์ ํ๊ดดํ๊ฑฐ๋ ๋ง๋ค์ง ์๊ณ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ด ํด๊ฒฐ ๋ฐฉ์์ ์คํํ ํ์ ์ฐ๋ฆฌ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ด ๋์ฑ ์ํํ๊ณ ๋๋์ด ๋์ฑ ์ข๋ค๋ ๊ฒ์ ๋๋ ์ ์๋ค.์ค๋ น ๋ค ๋์ ์ฌ์ฉํ๋ค๊ณ ํด๋ ๋๋ ๊ทธ๊ฒ์ ๋ณผ ์ ์๋ค.๋จ์ง ๋งค๋๋ฌ์ด ๊ฒ ์์ฒด๊ฐ ํฐ ์ฅ์ ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ถํ์ํ ์์ฒญ์ผ๋ก ์ฐ๋ฆฌ ์๋ฒ๋ฅผ ๊ณต๊ฒฉํ์ง ๋ง์ธ์!API ์๋ํฌ์ธํธ์ ๋ํ ๋ช ๊ฐ์ง ์ ํ์ ์ค์ผ ์ ์์ต๋๋ค.
์ต์ข ์ฌ์ฉ์๋ถํฐ ์ดํด๊ด๊ณ์, ๊ทธ๋ฆฌ๊ณ ์ค์ ๊ฐ๋ฐ์๊น์ง ์ด ํจ์น๋ ๋ชจ๋ ์ฌ๋์๊ฒ ์น๋ฆฌ์ด๋ค.
Git ์ฌ๊ตฌ๋งค ์ฝ๋
๋๋ ๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ์๋ ํ๋ก์ ํธ์ ์ฐ๋ฆฌ๊ฐ ์ฑํํ ํด๊ฒฐ ๋ฐฉ์์ ์ฐพ์ ์ ์๋ ํ๋งค ํ์๋ฅผ ๋ง๋ค์๋ค
LINK
**์ด ๋ด์ฉ์ ์ข์ํ์ ๋ค๋ฉด ์ฌ์ฅ์ด๋ ์ ๋์ฝ์ ํด๋ฆญํ์ธ์!
์ ์ ํ์ ์ฝ๊ณ ์ถ์ผ๋ฉด ์ ๋์ฝ ์๋ ์ฑ ๊ฐํผ ๋ฒํผ์ ํด๋ฆญํ์ธ์**
๐์ธ์ฌํ๋คMedium | |
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฒ๋์ ๋ ์ด์์์ด ์๋ VueJS ํ์ด์ง!๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ์!), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/lampewebdev/vuejs-pages-with-dynamic-layouts-problems-and-a-solution-4460ํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค