src>components>BoardForm.vue
<template>
<form ~~@submit.prevent="saveBoard"~~>
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Title</label>
<input
~~v-model="boardForm.title"~~
:value="title"
@input="$emit('update:title', $event.target.value)"
type="text" class="form-control"
id="title" />
</div>
<div class="mb-3">
<label for="content" class="form-label">Content</label>
<textarea
~~v-model="boardForm.content"~~
:value="content"
@input="$emit('update:content', $event.target.value)"
class="form-control" id="content"
rows="3"
></textarea>
</div>
~~<div class="pt-3 d-flex gap-2">
<button type="button" class="btn btn-outline-secondary" @click="boardListPage">List</button>
<button class="btn btn-success">Save</button>
</div>~~
<slot name='actions'></slot>
</form>
</template>
<script setup>
defineProps({
title: String,
content: String,
})
defineEmits({
'update:title', 'update:content'
})
</script>
<aside> 🧑💻
@submit
지우기
button은 <slot>
으로 정의하여 부모 컴포넌트에서 전달받기 name='actions'
받을 데이터 title
, content
는 defineProps로 데이터 타입 정의
다중 v-model
을 구현하기 위해 defineEmits에서 update:*data*
로 정의
input에서 v-model
을 구현할 때는 v-bind:value
에 Props를 넣고, @input
이벤트로 값을 받는다
이벤트객체를 이벤트에서 받을 때 $event
로 받는다. $event.target.value
로 가져오기
content
도 적용
</aside>
<template>
<div>
<h1>Create Board</h1>
<hr />
<BoardForm
v-model:title="BoardForm.title"
v-model:content="BoardForm.content"
@submit.prevent="saveBoard"
>
<template #actions>
<div class="pt-3 d-flex gap-2">
<button type="button" class="btn btn-outline-secondary" @click="boardListPage">List</button>
<button class="btn btn-success">Save</button>
</div>
</template>
</BoardForm>
~~<form @submit.prevent="saveBoard">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Title</label>
<input v-model="boardForm.title" type="text" class="form-control" id="title" />
</div>
<div class="mb-3">
<label for="content" class="form-label">Content</label>
<textarea v-model="boardForm.content" class="form-control" id="content" rows="3"></textarea>
</div>~~
~~<div class="pt-3 d-flex gap-2">
<button type="button" class="btn btn-outline-secondary" @click="boardListPage">List</button>
<button class="btn btn-success">Save</button>
</div>
</form>~~
</div>
</template>
<script setup>
import BoardForm from '@/components/BoardForm.vue'
...
</script>
<BoardForm @submit.prevent="saveBoard" />
<aside> 🧑💻
@submit
이벤트를 이렇게 적으면 BoardForm
의 루트 요소인 <form>
에 상속된다
</aside>
<template>
<div>
<h1>Board Edit</h1>
<hr />
<BoardForm
@submit.prevent="editBoard"
v-model:title="boardForm.title"
v-model:content="boardForm.content"
>
<template #actions>
<div class="pt-3 d-flex gap-2">
<button type="button" class="btn btn-outline-danger" @click="boardDetailPage">
Cancel
</button>
<button class="btn btn-outline-success">Save</button>
</div>
</template>
</BoardForm>
~~<form @submit.prevent="editBoard">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Title</label>
<input v-model="boardForm.title" type="text" class="form-control" id="title" />
</div>
<div class="mb-3">
<label for="content" class="form-label">Content</label>
<textarea v-model="boardForm.content" class="form-control" id="content" rows="3"></textarea>
</div>
</form>~~
<AppAlert :items="alerts" />
</div>
</template>
<script setup>
import BoardForm from '@/components/BoardForm.vue'
...
</script>
component/AppPagination.vue
에 붙여넣기
상위 컴포넌트에서 전달받을 Props 정의
<script setup>
defineProps({
currnetPage: {
type: Number,
required: true,
},
pageCount: {
type: Number,
required: true,
},
})
</script>
params._page
⇒ currentPage
<template>
<nav class="mt-5 bg-dart" aria-label="Page navigation example">
<ul class="pagination justify-content-center text-light">
<!-- prev -->
<li class="page-item" :class="{ disabled: currentPage <= 1 }">
<a class="page-link" href="#" aria-label="Previous" @click.prevent="--currentPage">
<span aria-hidden="true">«</span>
</a>
</li>
<!-- page -->
<li
v-for="page in pageCount"
:key="page"
class="page-item"
:class="{ active: currentPage === page }"
>
<a class="page-link" href="#" @click.prevent="currentPage = page">{{ page }}</a>
</li>
<!-- next -->
<li class="page-item" :class="{ disabled: currentPage >= pageCount }">
<a class="page-link" href="#" aria-label="Next" @click.prevent="++currentPage">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</template>
v-bind:class ⇒ computed로 변경
<!-- prev -->
<li class="page-item" :class="isPrevPage">
<a class="page-link" href="#" aria-label="Previous" @click.prevent="--currentPage">
<span aria-hidden="true">«</span>
</a>
</li>
...
<!-- next -->
<li class="page-item" :class="isNextPage">
<a class="page-link" href="#" aria-label="Next" @click.prevent="++currentPage">
<span aria-hidden="true">»</span>
</a>
</li>
const isPrevPage = computed(() => ({
disabled: props.currentPage <= 1,
}))
const isNextPage = computed(() => ({
disabled: props.currentPage >= props.pageCount,
}))