Feat: Add article write form
This commit is contained in:
parent
2fb1f9e234
commit
034e4b1126
130
src/components/article/ArticleForm.vue
Normal file
130
src/components/article/ArticleForm.vue
Normal file
@ -0,0 +1,130 @@
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import BoardHeader from './BoardHeader.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { addArticle } from '@/api/article';
|
||||
|
||||
const router = useRouter();
|
||||
const title = ref('');
|
||||
const text = ref('');
|
||||
const titleDiv = ref();
|
||||
const textDiv = ref();
|
||||
const titleErrorMsg = ref('');
|
||||
const textErrorMsg = ref('');
|
||||
|
||||
watch(title, (value) => {
|
||||
if (value.trim()) {
|
||||
titleErrorMsg.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
watch(text, (value) => {
|
||||
if (value.trim()) {
|
||||
textErrorMsg.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
function handleSubmit() {
|
||||
if (!title.value.trim()) {
|
||||
titleErrorMsg.value = '제목을 입력해주세요.';
|
||||
titleDiv.value.focus();
|
||||
return;
|
||||
}
|
||||
if (!text.value.trim()) {
|
||||
textErrorMsg.value = '내용을 입력해주세요.';
|
||||
textDiv.value.focus();
|
||||
return;
|
||||
}
|
||||
const article = {
|
||||
title: title.value,
|
||||
text: text.value,
|
||||
};
|
||||
|
||||
addArticle(article, ({ data }) => {
|
||||
if (!isNaN(data)) {
|
||||
router.replace({ name: 'article', params: { id: data } });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
titleDiv.value.focus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BoardHeader>
|
||||
<template #title>
|
||||
<h1>글쓰기</h1>
|
||||
</template>
|
||||
</BoardHeader>
|
||||
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<div :class="['inputWrapper', titleErrorMsg ? 'error' : '']">
|
||||
<label for="title">제목</label>
|
||||
<input id="title" ref="titleDiv" v-model="title" />
|
||||
<div class="errorMessage" v-if="titleErrorMsg">{{ titleErrorMsg }}</div>
|
||||
</div>
|
||||
<div :class="['inputWrapper', textErrorMsg ? 'error' : '']">
|
||||
<label for="text">내용</label>
|
||||
<textarea id="text" ref="textDiv" v-model="text"></textarea>
|
||||
<div class="errorMessage" v-if="textErrorMsg">{{ textErrorMsg }}</div>
|
||||
</div>
|
||||
<button type="button" @click="handleSubmit">작성</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.inputWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
#title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#text {
|
||||
font-size: 1rem;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.error input,
|
||||
.error textarea {
|
||||
border-color: var(--color-error);
|
||||
outline-color: var(--color-error);
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
color: var(--color-error);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px;
|
||||
background-color: var(--color-primary);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
transition:
|
||||
scale 0.25s,
|
||||
background-color 0.25s;
|
||||
}
|
||||
|
||||
button:active {
|
||||
scale: 0.98;
|
||||
background-color: var(--color-primary-soft);
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user