작성
·
57
0
<template>
<div>
<h2>게시글 등록</h2>
<hr class="my-4" />
<PostForm
v-model.title="form.title"
v-model.content="form.content"
@submit.prevent="savePost"
>
<template #actions>
<div class="pt-4">
<button
type="button"
class="btn btn-outline-dark me-2"
@click="goPostListPage"
>
목록
</button>
<button class="btn btn-primary">저장</button>
</div>
</template>
</PostForm>
<!-- <form>
<div class="mb-3">
<label for="title" class="form-label">제목</label>
<input
v-model="form.title"
type="text"
class="form-control"
id="title"
/>
</div>
<div class="mb-3">
<label for="content" class="form-label">내용</label>
<textarea
v-model="form.content"
class="form-control"
id="content"
rows="3"
></textarea>
</div> -->
<!-- <div class="pt-4">
<button
type="button"
class="btn btn-outline-dark me-2"
@click="goPostListPage"
>
목록
</button>
<button type="button" class="btn btn-primary" @click="goPostListPage">
저장
</button>
</div>
</form>-->
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
import { createPost } from "@/api/posts";
import { ref } from "vue";
import PostForm from "@/components/posts/PostForm.vue";
const router = useRouter();
const form = ref({
id: 0,
title: "",
content: "",
createAt: Date.now(),
});
const savePost = () => {
try {
// const data = { ...form.value, createAt: Date.now() };
createPost({ ...form.value });
goPostListPage();
// console.log("savePost data", data);
} catch (err) {
console.log("err", err);
}
};
// 목록이동
const goPostListPage = () => {
router.push({
name: "PostList",
});
};
</script>
<style lang="scss" scoped></style>
<template>
<form>
<div class="mb-3">
<label for="title" class="form-label">제목</label>
<!-- v-model을 사용하지 않고, v-bind와 @input 이벤트를 사용하여 양방향 데이터 바인딩 -->
<input
: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">내용</label>
<textarea
:value="content"
@input="$emit('update:content', $event.target.value)"
class="form-control"
id="content"
rows="3"
></textarea>
</div>
<!-- <div class="pt-4">
<button
type="button"
class="btn btn-outline-dark me-2"
@click="goPostListPage"
>
목록
</button>
<button type="button" class="btn btn-primary" @click="goPostListPage">
저장
</button>
</div> -->
<slot name="actions"></slot>
</form>
</template>
<script setup>
defineProps({
title: String,
content: String,
});
// update:props데이터명
// 양방향 데이터 바인딩을 위해 사용 : 부모에게 내려받은 props를 업데이트
// update 접두사는 v-model과 함께 사용되는 이벤트 이름
defineEmits(["update:title", "update:content"]);
</script>
<style lang="scss" scoped></style>
{
"posts": [
{
"id": 2,
"title": "제목2",
"content": "내용2",
"createAt": "2021-01-02"
},
{
"id": 3,
"title": "제목3",
"content": "내용3",
"createAt": "2021-01-03"
},
{
"id": 4,
"title": "제목4",
"content": "내용4",
"createAt": "2021-01-04"
},
{
"title": "제목8",
"content": "내용83333333",
"createAt": "2021-01-08",
"id": 8
},
{
"id": 9,
"title": "",
"content": "",
"createAt": 1750817841654
},
{
"id": 10,
"title": "",
"content": "",
"createAt": 1750828553704
}
]
}
title,content값이 비어서 저장되는데 제가 혹시 어떤 부분을 잘못 작성했는지 ㅜㅜ 알고싶습니다.
답변 3
0
v-model 구문에 오타가 있습니다
현재 코드 (잘못된 구문):
<PostForm
v-model.title="form.title" ← 잘못됨
v-model.content="form.content" ← 잘못됨
@submit.prevent="savePost"
>
올바른 구문:
<PostForm
v-model:title="form.title" ← 콜론(:) 사용
v-model:content="form.content" ← 콜론(:) 사용
@submit.prevent="savePost"
>
.
(점): Vue 수식어 (modifier) - 예: v-model.lazy
:
(콜론): props 바인딩 - 예: v-model:title
현재 상황:.title
, .content
를 수식어로 인식해서 실제 데이터 바인딩이 안 되고 있어서 빈 값으로 저장되는 겁니다.
PostForm.vue는 정상이고, 부모 컴포넌트에서 v-model 구문만 수정하면 해결됩니다.
0
0
안녕하세요, 인프런 AI 인턴입니다. bebe님.
제공하신 코드를 보면서 title과 content 값이 비어서 저장되는 문제를 진단해보겠습니다.
양방향 바인딩 문제: PostForm 컴포넌트에서 부모 컴포넌트가 ref로 관리하는 form.title
과 form.content
값을 업데이트 해야 합니다. 그러나 현재 PostForm.vue
에서는 v-model 대신 직접 이벤트를 통해 값을 업데이트하고 있습니다. 이 방식은 잘못 구현될 경우 데이터가 부모로 제대로 전달되지 않을 수 있습니다.
v-model
의 이벤트 사용: 현재 v-model
을 통해 emit하는 이벤트는 update:title
과 update:content
입니다. 이 이벤트가 부모 컴포넌트에서 적절히 수신되고 있는지 확인해야 합니다.
부모 컴포넌트에서 데이터 설정: 부모 컴포넌트에서 적절하게 v-model.title
과 v-model.content
가 전달되고 있는지 확인합니다. 간단히 올바르게 동작하는지 콘솔 로그를 추가하여 값이 제대로 변경되는지 확인하는 것도 좋습니다.
v-model
의 올바른 사용: PostForm
컴포넌트에서 v-model:title
과 v-model:content
를 제대로 연결했는지 확인합니다. 아래와 같이 단순히 v-model
을 사용하여 양방향 바인딩 할 수 있습니다:
<PostForm v-model:title="form.title" v-model:content="form.content"></PostForm>
이벤트 수신 확인: 부모 컴포넌트에서 update:title
, update:content
이벤트가 적절히 수신되고 있는지 확인합니다. 이 이벤트가 수신되지 않으면 데이터가 업데이트되지 않습니다.
콘솔 로그 추가: 데이터가 변경될 때마다 콘솔에 그 값을 출력해 보세요. 그러면 데이터 바인딩 과정을 추적하는 데 도움이 됩니다.
유사한 문제를 겪은 경우 해결된 다른 사례를 참고하여 효과적으로 문제를 해결할 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.