Why is the data I'm binding in a Vue 3 form not updating when printed on the console via a function?
P粉354602955
2023-09-04 11:50:33
<p>I have created a form component in Vue 3 and I am trying to bind a reference object to an input element, based on my understanding of two way binding and the way Vue has behaved in my past works I would expect any changes will affect my reference to the immediate object without any manipulation like I have to do with React components by triggering the "onChange" reactive event. </p>
<p>However, when I click the "Save" button to trigger the function that outputs the referenced object, it seems to only retain the value that was originally loaded and not any changes I made in the input. Can anyone explain why? </p>
<p>This is the code for my component. It will load in a popup window.</p>
<pre class="brush:php;toolbar:false;"><script setup lang="ts">
import type { Activity } from '@/models/activity';
import { ref } from "vue";
import Button from '../../common/Button.vue';
defineEmits([
"close-form"
]);
const props = defineProps<{
title?: String,
activity?: Activity,
editMode: Boolean
}>();
const initialState = props.activity ?? {
id: '',
title: '',
category: '',
description: '',
date: '',
city: '',
venue: ''
}
const currActivity = ref<Activity>(initialState);
const handleSubmit = () => {
console.log(currActivity.value);
}
// const handleInputChange = (event: Event) => {
// const {name, value} = event.target as HTMLInputElement;
// console.log(name, value);
// // currActivity.value[name] = value;
// }
</script>
<template>
<form
class="grid grid-cols-5 gap-4 mb-8"
@submit="handleSubmit"
autocomplete="off"
>
<h2
v-if="title"
class="col-span-5 mb-4 text-white text-3xl font-semibold"
>
{{ title }}
</h2>
<input type="text" placeholder='Title' class='col-span-3 mb-4 px-2 py-1 rounded' :value="currActivity.title" name="title" />
<input type="text" placeholder='Category' class='mb-4 px-2 py-1 rounded' :value="currActivity.category" name="category" />
<textarea placeholder='Description' class='col-span-5 mb-4 px-2 py-1 rounded' :value="currActivity.description" name="description" />
<input type="text" placeholder='Date' class='px-2 py-1 rounded' :value="currActivity.date" name="date" />
<input type="text" placeholder='City' class='px-2 py-1 rounded' :value="currActivity.city" name="city" />
<input type="text" placeholder='Venue' class='px-2 py-1 rounded' :value="currActivity.venue" name="venue" />
<div
v-if="editMode && activity"
class="flex justify-end col-span-2"
>
<Button
text="Save"
icon="fa-floppy-disk"
type="send"
@click="handleSubmit"
/>
<Button
text="Close"
icon="fa-xmark"
type="cancel"
@click="$emit('close-form')"
/>
</div>
<div
v-else
class='flex justify-end col-span-2'
>
<Button
text="Post"
icon="fa-paper-plane"
type="send"
@click="handleSubmit"
/>
</div>
</form>
</template></pre>
<p>You may notice the commented functions in my script. I tried copying the React method and handling the change using a change event triggered by "@change" on the input element. I later deleted them as this didn't seem to work. I've left the comments feature in, but just in case anyone finds it helpful in finding the issue. </p>
You need to use
v-model
instead of:value
for two-way binding: