1. 선택 메뉴가 있는 바닥 내비게이션 만들기

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@3.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app>
<!-- 내용 영역에 선택된 메뉴명을 표시함. flexbox를 이용해서 가운데 정렬시킴 -->
<v-content>
<v-card height="100%" class="d-flex display-2 align-center justify-center">선택: {{ sSelect }}</v-card>
</v-content>
<!-- 하단 영역에 바닥 네비게이션 메뉴를 absolute로고정시켜 표시함 -->
<v-footer>
<!-- 선택된 메뉴는 sSelect 데이터를 연동시켜 바인딩함 -->
<v-bottom-navigation absolute v-model="sSelect" dark >
<!-- 아이콘 버튼 3개를 표시함 -->
<v-btn text value="자전거">
자전거
<v-icon>directions_bike</v-icon>
</v-btn>
<v-btn text value="지하철">
지하철
<v-icon>subway</v-icon>
</v-btn>
<v-btn text value="버스">
버스
<v-icon>directions_bus</v-icon>
</v-btn>
</v-bottom-navigation>
</v-footer>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
sSelect: '자전거'
}
})
</script>
</body>
</html>
2. 사용자 정보가 담기 탐색 서랍 만들기

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@3.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.2.x/dist/vuetify.min.css" rel="stylesheet">
<!-- 폰트어썸 아이콘을 사용하기 위해 연결함 -->
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
</head>
<body>
<div id="app">
<v-app>
<!-- 상단영역에 툴바를 배치하고 좌측에 메뉴 아이콘 넣음 -->
<v-app-bar app color="primary" dark>
<!-- 메뉴 아이콘이 눌리면 클릭기능을 비활성화시킴 -->
<v-app-bar-nav-icon @click.stop="bDrawer = !bDrawer">
</v-app-bar-nav-icon>
<v-toolbar-title>Header입니다.</v-toolbar-title>
</v-app-bar>
<!-- bDrawer가 True이면 탐색 서랍 사용하도록 바인딩함 -->
<v-navigation-drawer absolute temporary v-model="bDrawer">
<!-- 안쪽에 툴바로 플랫 스타일로 메뉴 제목을 작성 -->
<v-toolbar flat height="70px">
<v-list>
<v-list-item>
<v-list-item-avatar>
<img src="https://randomuser.me/api/portraits/men/44.jpg">
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title class="title">홍길동</v-list-item-title>
<v-list-item-subtitle>로그인</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-toolbar>
<v-divider></v-divider>
<!-- 제목 밑에 메뉴명을 목록으로 작성. 안쪽여백은 pt-3으로 설정 -->
<v-list class="pt-3">
<!-- 배열에 있는 데이터를 반복문으로 가져와 링크, 제목, 아이콘을 렌더링함 -->
<v-list-item v-for="item in aMenu_items" :key="item.title" :href="item.link">
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<!-- 내용 영역에 선택된 메뉴명을 표시함. flexbox를 이용해서 가운데 정렬시킴 -->
<v-content>
<v-card height="100%" class="d-flex display-2 align-center justify-center">선택: {{ sSelect }}</v-card>
</v-content>
<!-- 하단 영역에 바닥 네비게이션 메뉴를 absolute로고정시켜 표시함 -->
<v-footer>
<!-- 선택된 메뉴는 sSelect 데이터를 연동시켜 바인딩함 -->
<v-bottom-navigation absolute v-model="sSelect" dark >
<!-- 아이콘 버튼 3개를 표시함 -->
<v-btn text value="자전거">
자전거
<v-icon>directions_bike</v-icon>
</v-btn>
<v-btn text value="지하철">
지하철
<v-icon>subway</v-icon>
</v-btn>
<v-btn text value="버스">
버스
<v-icon>directions_bus</v-icon>
</v-btn>
</v-bottom-navigation>
</v-footer>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
// 버튼이 눌리면 비활성화되도록 하는 토글 변수
bDrawer: false,
// 배열로 메뉴의 제목, 아이콘, 링크를 준비
aMenu_items: [{
title: '스타벅스',
icon: 'fa-coffee',
link: 'http://www.starbucks.com'
},
{
title: '애플',
icon: 'mdi-apple',
link: 'http://www.apple.com'
},
{
title: '페이스북',
icon: 'mdi-facebook-box',
link: 'http://www.facebook.com'
}
],
sSelect: '자전거'
}
})
</script>
</body>
</html>
3. 라우터로 멀티 페이지 관리하는 SPA 만들기

App.vue
<template>
<v-app>
<!-- 앱바테마를 primary(파랑색)로 설정합니다. -->
<v-app-bar app color="primary" dark>
<!-- 좌측에 메뉴 아이콘 넣음 -->
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>멀티 페이지</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</v-app-bar>
<!-- 내용영역에 라우터 페이지 렌더링 -->
<v-content>
<!-- 페이지 장면전환 효과 넣기 -->
<v-slide-x-transition mode="out-in">
<router-view></router-view>
</v-slide-x-transition>
</v-content>
<!-- 툴바테마를 secondary로 설정합니다. -->
<v-footer color="secondary" fixed dark>
<div class="mx-auto">CODE-DESIGN.web.app</div>
</v-footer>
</v-app>
</template>
components/main_page.vue
<!-- 메인 페이지의 뷰화면을 디자인함 -->
<template>
<v-container>
<p class="display-1 my-4">메인 페이지입니다.</p>
<v-divider></v-divider>
<p class="display-4 my-4">메인 페이지입니다.</p>
<div class="text-center">
<!-- 버튼에서 fab, large 어트리뷰트를 사용해서 큰 원으로 설정-->
<v-btn fab large class="mt-5" color="purple" dark to="/sub">
<v-icon>mdi-arrow-right</v-icon>
</v-btn>
</div>
</v-container>
</template>
components/sub_page.vue
<!-- 서브 페이지의 뷰화면을 디자인함 -->
<template>
<v-container>
<p class="display-1 my-4">서브 페이지입니다.</p>
<v-divider></v-divider>
<p class="display-4 my-4">서브 페이지입니다.</p>
<div class="text-center">
<!-- 버튼에서 fab large 어트리뷰트를 사용해서 큰 원으로 설정-->
<v-btn fab large class="mt-5" color="teal" dark to="/main">
<v-icon>mdi-replay</v-icon>
</v-btn>
</div>
</v-container>
</template>
router.js
import Vue from 'vue'
import Router from 'vue-router'
// main_page와 sub_page 두개의 컴포넌트 모듈을 가져옴
import main_page from '@/components/main_page'
import sub_page from '@/components/sub_page'
Vue.use(Router)
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
// 첫 루트 페이지는 main_page로 설정해 둠
path: '/', name: 'home', component: main_page
},
{
path: '/main', name: 'main_page', component: main_page
},
{
path: '/sub', name: 'sub_page', component: sub_page
}
]
})
4. Vuex 로 상태값 관리하는 SPA 만들기

1. 프로젝트 vue-sample 디렉토리 생성
2. vue-sample 디렉토리 이동
3. vue 프로젝트 생성
vue create .
4. manually select featres 선택
vue 2 선택
router 와 vuex 체크
5. vue add vuetify

App.vue
<template>
<v-app>
<!-- 툴바테마를 primary(파랑색)로 설정합니다. -->
<v-app-bar app color="primary" dark>
<!-- 좌측에 메뉴 아이콘 넣음 -->
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>멀티 페이지</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</v-app-bar>
<!-- 내용영역에 라우터 페이지 렌더링 -->
<v-content>
<!-- 페이지 장면전환 효과 넣기 -->
<v-slide-x-transition mode="out-in">
<router-view></router-view>
</v-slide-x-transition>
</v-content>
<!-- 툴바테마를 secondary로 설정합니다. -->
<v-footer color="secondary" fixed dark>
<div class="mx-auto">macaroics.net</div>
</v-footer>
</v-app>
</template>
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
sTitle: ''
},
getters: {
// store의 상태값을 반환함
fnGetData(state) {
return state.sTitle;
},
},
mutations: {
// 매개변수로 전달받은 값을 store에 저장
fnSetData: function (state, payload) {
return state.sTitle = payload
}
},
actions: {
},
modules: {
}
})
router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import main_page from '@/components/main_page'
import sub_page from '@/components/sub_page'
Vue.use(VueRouter)
const routes = [
{
path: '/', name: 'home', component: main_page
},
{
path: '/main', name: 'main_page', component: main_page
},
{
path: '/sub', name: 'sub_page', component: sub_page
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
components/main_page.vue
<template>
<v-container>
<v-content>
<div class="text-center display-3 my-4">메인 페이지입니다.</div>
<v-row>
<v-col offset-sm="1" sm="10">
<!-- 제목을 입력받으면 sTitle 데이터와 바인딩 시켜 store에
저장함-->
<v-text-field label="제목" v-model="sTitle">
</v-text-field>
</v-col>
</v-row>
<div class="text-center">
<v-btn large class="mt-5" color="purple" dark @click="fnSetTitle">
확 인
</v-btn>
</div>
</v-content>
</v-container>
</template>
<script>
export default {
// store에 있는 데이터를 가져옴
data() {
return {
sTitle: this.$store.getters.fnGetData
}
},
methods: {
// 입력받은 제목을 store에 저장
fnSetTitle() {
this.$store.commit('fnSetData', this.sTitle);
this.$router.push('/sub');
}
}
}
</script>
components/sub_page.vue
<template>
<v-container>
<v-content>
<div class="text-center display-1 my-4">서브 페이지입니다.</div>
<v-divider></v-divider>
<!-- store에 있는 sTitle 값을 가져와 표시함 -->
<div class="text-center display-3 my-4">{{ sTitle }}</div>
<div class="text-center">
<v-btn fab large class="mt-5" color="teal" dark to="/main">
<v-icon>mdi-replay</v-icon>
</v-btn>
</div>
</v-content>
</v-container>
</template>
<script>
export default {
// store에 있는 fnGetData 함수를 호출하여 sTitle 값을 가져옴
data() {
return {
sTitle: this.$store.getters.fnGetData,
}
}
}
</script>
출처 :
Do it! 프로그레시브 웹앱 만들기
반응형 웹 개발부터 하이브리드 앱 배포까지 PWA 완전 정복!
김응석 저자(글)
이지스퍼블리싱 · 2020년 08월 06일
8.5(7개의 리뷰)
도움돼요(50%의 구매자)
https://product.kyobobook.co.kr/detail/S000001817978
















댓글 ( 4)
댓글 남기기