읽기 뷰 (ReadView) 생성
1. src\views\LunchMenu에서 LunchMenuReadView.vue 파일을 생성합니다.

<template>
<div>점심 메뉴 보기</div>
</template>
<script>
export default {
setup() {
}
}
</script>
2. src\router\index.js에서 LunchMenuReadView.vue를 import하고 children(칠드런)에 추가합니다.

:
import LunchMenuReadView from '@/views/LunchMenu/LunchMenuReadView.vue'
const routes = [
:
{
path: '/lunchmenu',
component: LunchMenuView,
children : [
:
{
path: ':seq',
name: 'lunchmenuread',
component: LunchMenuReadView
}
]
}
]
:
:seq는 웹 경로에 있는 파라미터입니다.
파라미터는 콜론 :으로 표시됩니다.
/lunchmenu/1
웹 경로에 있는 파라미터(동적 세그먼트)를 사용한 동적으로 라우팅하게 합니다. → 파라미터를 사용한 동적 라우트 매칭 (https://router.vuejs.kr/guide/essentials/dynamic-matching.html)
2. src\views\LunchMenu\LunchMenuListView.vue 파일에서 <li>가 클릭되면 함수(핸들러)가 호출되도록 @click(v-on:click)를 사용합니다.

<template>
<div>점심 메뉴 리스트</div>
<div class="buttons">
<div class="right">
<router-link :to="{ name: 'lunchmenuadd' }" class="button blue">
<span>등록</span>
</router-link>
</div>
</div>
<div v-if="lunchMenuList.length == 0">
점심 메뉴가 없습니다.
</div>
<div v-else>
점심 메뉴가 {{ lunchMenuList.length }} 개 있습니다.
<ul class="menu-list">
<li class="menu-item" v-for="(lunchMenuItem, index) in lunchMenuList" :key="index"
@click="gotoLunchMenuRead(lunchMenuItem)">{{ lunchMenuItem.menu_name }}
</li>
</ul>
</div>
</template>
3. setup()에 <li>가 클릭되면 읽기 뷰 컴포넌트로 이동하기 위해서 라우터 인스턴스를 받고 router.push() 함수를 사용합니다. → Router 프로그램 방식
<script>
:
import { useRouter } from 'vue-router';
export default {
name : 'LunchMenuListView',
setup() {
const router = useRouter();
:
function gotoLunchMenuRead(lunchMenuItem) {
router.push({name : 'lunchmenuread', params : {seq : lunchMenuItem.seq}});
}
return {
:
gotoLunchMenuRead
}
},
}
</script>
name에는 route(라우트)를 생성할 때 부여한 이름을 사용합니다.
params에는 웹 경로에 있는 파라미터(콜론(:)으로 표시)인 :seq에 전달할 lunchMenuItem의 seq입니다.
router.push() 함수를 사용하면 routers에 등록되어 있는 router를 찾아 이동하게 됩니다.
(https://router.vuejs.kr/guide/essentials/navigation.html#Navigate-to-a-different-location)
4. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/1)

5. src\views\LunchMenu\LunchMenuListView.vue 파일에서 <li>에 있는 점심 메뉴 명을 클릭되면 이동하도록 router-link를 추가합니다. → Router 선언적 방식
<template>
<div>점심 메뉴 리스트</div>
<div class="buttons">
<div class="right">
<router-link :to="{ name: 'lunchmenuadd' }" class="button blue">
<span>등록</span>
</router-link>
</div>
</div>
<div v-if="lunchMenuList.length == 0">
점심 메뉴가 없습니다.
</div>
<div v-else>
점심 메뉴가 {{ lunchMenuList.length }} 개 있습니다.
<ul class="menu-list">
<li class="menu-item" v-for="(lunchMenuItem, index) in lunchMenuList" :key="index">
<router-link :to="{name : 'lunchmenuread', params : {seq: lunchMenuItem.seq}}">
{{ lunchMenuItem.menu_name }}
</router-link>
</li>
</ul>
</div>
</template>
name에는 route(라우트)를 생성할 때 부여한 이름을 사용합니다.
params에는 웹 경로에 있는 파라미터(콜론(:)으로 표시)인 :seq에 전달할 lunchMenuItem의 seq입니다.
6. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/)

LunchMenuListView.vue 파일에 있는 <style>에 menu-item를 추가했습니다.
<style>
.menu-item a {
color: white;
}
</style>
7. src\views\LunchMenu\LunchMenuReadView.vue 파일을 수정합니다.

<template>
<div>점심 메뉴 보기 {{ $route.params.seq }}</div>
{{ lunchMenuItem.menu_name }}
</template>
<script>
import { ref } from 'vue';
import { useRoute } from 'vue-router'
import axios from 'axios';
export default {
setup() {
const route = useRoute();
const lunchMenuItem = ref({});
function getLunchMenuItem() {
axios.get("http://127.0.0.1:9000/api/v1/lunchmenus/" + route.params.seq).then((res) => {
console.log(res);
lunchMenuItem.value = res.data.data;
}).catch((err) => {
console.log(err);
});
}
return {
lunchMenuItem,
getLunchMenuItem
}
},
mounted() {
this.getLunchMenuItem();
}
}
</script>
현재 라우트는 템플릿에서 $route로 접근할 수 있습니다.
라우트가 매칭되면 파라미터의 값은 컴포넌트에서 route.params로 노출됩니다
/lunchmenu/:seq → /lunchmenu/1
useRoute() 함수는 현재 라우트를 반환 합니다.
8. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/1)

9. 목록 버튼을 추가하고 버튼이 클릭되면 점심 메뉴 리스트로 이동하도록 함수를 생성하고 리턴합니다.

<template>
:
<div class="buttons">
<div class="right">
<button class="button" @click="listClick">목록</button>
</div>
</div>
</template>
<script>
import { useRoute, useRouter } from 'vue-router'
export default {
setup() {
:
const router = useRouter();
:
function listClick() {
router.back();
}
return {
:
listClick
}
},
:
}
</script>
10. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/1)

수정 생성 – 등록 뷰 (AddView) 재사용
1. src\router\index.js에서 수정 라우트를 children(칠드런)에 추가합니다.

:
const routes = [
:
{
path: '/lunchmenu',
component: LunchMenuView,
children : [
:
{
path: ':seq/edit',
name: 'lunchmenuedit',
component: LunchMenuAddView
}
]
}
]
:
/lunchmenu/1/edit
컴포넌트는 등록 컴포넌트를 사용합니다.
2. 수정 버튼을 추가하고 버튼이 클릭되면 점심 메뉴 수정으로 이동하도록 함수를 생성하고 리턴합니다.

<template>
:
<div class="buttons">
<div class="left">
<button class="button" @click="editClick">수정</button>
</div>
:
</div>
</template>
<script>
:
export default {
setup() {
:
function editClick() {
var result = confirm("수정하시겠습니까?");
if (result) {
router.push({name : 'lunchmenuedit', params : {seq : route.params.seq}});
}
}
return {
:
editClick
}
},
:
}
</script>
<style>
.buttons > div.left {
position:absolute;
height:32px;
left:0;
}
</style>
3. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/1)

4. src\views\LunchMenu\LunchMenuAddView.vue 파일에서 $route.name으로 등록인지 수정인지 확인하여 메지지를 변경하고 버튼을 교체합니다.

<template>
<div>점심 메뉴 {{ $route.name == 'lunchmenuedit' ? '수정' : '등록' }}</div>
<form class="lunchMenuForm">
<div>
<label for="lunchMenuName">점심 메뉴 명 :</label>
<input type="text" id="lunchMenuName"
placeholder="점심 메뉴 명을 입력하세요."
v-model="lunchMenuName"/>
</div>
</form>
<div class="buttons">
<div class="right">
<button v-if="$route.name == 'lunchmenuedit'" class="button blue" @click="editClick">수정</button>
<button v-else class="button blue" @click="addClick">등록</button>
<button class="button" @click="cancelClick">취소</button>
</div>
</div>
</template>
수정 버튼이 클릭되면 axios의 put() 함수를 사용하여 APIServer에 점심 메뉴가 수정되도록 합니다.
<script>
import { reactive, toRefs, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
:
export default {
setup() {
:
const route = useRoute();
:
function editClick() {
if (state.lunchMenuName == "") {
alert("점심 메뉴 명을 입력하세요.");
lunchMenuNameInput.value.focus();
return;
}
var result = confirm("수정하시겠습니까?");
if (result) {
const lunchMenuItem = { menuName : state.lunchMenuName };
axios.put("http://127.0.0.1:9000/api/v1/lunchmenus/"+ route.params.seq, lunchMenuItem).then(() => {
router.replace({name : 'lunchmenuread', params : {seq: route.params.seq}};
}).catch((err) => {
console.log(err);
});
}
}
onMounted()에 콜백으로 getLunchMenuItem() 함수를 등록하여 APIServer에서 점심 메뉴를 가져오도록 합니다.
function getLunchMenuItem() {
axios.get("http://127.0.0.1:9000/api/v1/lunchmenus/" + route.params.seq).then((res) => {
state.lunchMenuName = res.data.data.menu_name;
}).catch((err) => {
console.log(err);
});
}
:
onMounted(()=>{
if (route.name == "lunchmenuedit") {
getLunchMenuItem();
}
});
return {
:
editClick
}
}
}
5. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/1/edit)



6. 마운트 된 후 점심 메뉴 명 입력란으로 포커스가 가기 위해서 <template>를 참조하여 처리해야 합니다.
<template>
:
<input type="text" id="lunchMenuName" placeholder="점심 메뉴 명을 입력하세요."
v-model="lunchMenuName"
ref="lunchMenuNameInput"/>
:
</template>
<script>
import { …, ref } from 'vue';
export default {
setup() {
:
const lunchMenuNameInput = ref(null);
:
onMounted(()=>{
:
lunchMenuNameInput.value.focus();
});
return {
:
lunchMenuNameInput
}
}
}
</script>
DOM에 접근하기 위해서 ref란 특수 속성을 사용합니다.
ref 속성 값과 일치하는 이름으로 ref를 선언해야 합니다.
초기값은 null 이어야 합니다. 마운트 된 후 DOM객체로 변경됩니다.
focus() 함수로 input에 포커스가 이동됩니다.
템플릿 참조에 대한 설명을 참고하세요. (https://ko.vuejs.org/guide/essentials/template-refs.html)
삭제 – 읽기 뷰 (ReadView) 사용
1. 삭제 버튼을 추가하고 버튼이 클릭되면 점심 메뉴가 삭제되도록 함수를 생성하고 리턴합니다.

<template>
:
<div class="buttons">
<div class="left">
<button class="button" @click="editClick">수정</button>
<button class="button" @click="deleteClick">삭제</button>
</div>
:
</div>
</template>
<script>
:
export default {
setup() {
:
async function deleteClick() {
var result = confirm("삭제하시겠습니까?");
if (result) {
try {
const res = await axios.delete("http://127.0.0.1:9000/api/v1/lunchmenus/" + route.params.seq);
if (res.data.code == 200) {
alert("삭제되었습니다.");
router.push({name : 'lunchmenulist’});
} else {
alert("삭제되지 않았습니다.");
}
} catch(err) {
console.log(err);
}
}
}
return {
:
deleteClick
}
},
:
}
</script>
2. 웹 브라우저에서 확인하기 (http://127.0.0.1:8080/lunchmenu/4)



라우터와 현재 라우트에 접근하기

라우터와 현재 라우트에 대한 접근 방법을 참고하세요.
(https://router.vuejs.kr/guide/#Accessing-the-router-and-current-route)
변수와 함수 사용


'Vue.js 3 & NodeJS > 사내교육 - 점심 메뉴' 카테고리의 다른 글
| [9] Backend 개발 - 사용자 API 개발, 인증 처리, ID Token (0) | 2026.08.04 |
|---|---|
| [8] Backend 개발 - 사용자 API 개발, 인증 처리, Session + HTTP Cookie (0) | 2026.08.04 |
| [6] Frontend 개발 - 등록 뷰 (AddView) 생성 (0) | 2026.08.03 |
| [5] Backend 개발 - API Server 개발, Node.JS + Search (0) | 2026.08.03 |
| [4] Backend 개발 - API Server 개발, Node.JS + Paging (0) | 2026.08.03 |