Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is my bound data in a Vue 3 form not being updated when printed on the console via a function?

I have created a form component in Vue 3 where I am trying to bind a reference object to input elements and from my understanding of two-way binding and how Vue behaved for my past works, I expected any changes to affect my reference object immediately without requiring any manipulation like I would have had to for a React component by triggering the "onChange" react event.

However, when I click on the "Save" button to trigger a function that outputs the reference object, it only seems to keep my value loaded initially but not any changes I make from within the input. Can anybody explain why?

Here’s the code for my component. It loads inside a pop-up window.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<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>

You may notice a commented function in my script. I tried to replicate the React approach and handle the changes on the change event triggered using "@change" on the input elements. I removed these later as that didn’t seem to work. I kept the commented function however in case anyone finds it useful to locate the issue.

>Solution :

You need to make two-way binding using v-model instead of :value :

   <input type="text" placeholder='Title' 
        class='col-span-3 mb-4 px-2 py-1 rounded' v-model="currActivity.title" name="title" />
    
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading