Search code examples
javascriptreactjsformsvue.jscontrolled-component

How to create Vuejs controlled input form?


I'm used to creating controlled components in react using state; however, I'm new to Vue and would like to learn how I could recreate my code from react into something Vue could use. I want the input fields values to be store in a piece of data so that I could do something with them.

<template>
    <form @submit="handleSubmit" class="form form--signin">
        <h2 class="form__h2">Log into your account</h2>

        <label for="email">Email address</label>
        <input v-model="email" type="email" id="email" autoComplete="off"/>

        <label for="password">Password</label>
        <input v-model="password" type="password" id="password" autoComplete="off"/>

        <button class="form__btn">Login</button>
    </form>
</template>

<script>

import axios from 'axios';

export default {
    name: 'SignIn',
    data() {
        return {
            user: null,
            email: null,
            password: null
        }
    },
    methods: {
        handleSubmit(event) {
            event.preventDefault();
            this.login(this.email, this.password);
            this.email = '';
            this.password = '';
        },
        login(email, password) {
            axios.post('http://localhost:8000/api/v1/users/login', {
                email,
                password
            })
            .then(res => {
                // console.log(this.user);
                this.user = res.data.data.user;
                if(res.data.status === 'success') {
                    // setUserStatus(res.data.status);
                    window.setTimeout(() => {
                        window.location.assign('/');
                    }, 1500)
                }
            })
            .catch(err => console.log(err.response.data.message));
        }
    }, 
    mounted() {
        if (!this.user) return;

        console.log('Writing to session storage...');
        sessionStorage.setItem('user', JSON.stringify(this.user));
    }
}


Solution

  • This is how it would look like in Vue

    Vue.config.devtools = false;
    Vue.config.productionTip = false;
    
    const SignIn = Vue.component('sign-in', {
    
      template: `<form @submit="handleSubmit" className="form form--signin">
                <h2 className="form__h2">Log into your account</h2>
    
                <label htmlFor="email">Email address</label>
                <input v-model="email" type="email" id="email" autoComplete="off"/>
    
                <label htmlFor="password">Password</label>
                <input v-model="password" type="password" id="password" autoComplete="off"/>
    
                <button className="form__btn">Login</button>
            </form>`,
      data() {
        return {
          user: null,
          email: null,
          password: null,
        }
      },
      methods: {
        handleSubmit(event) {
    
          this.login(this.email, this.password)
          this.email = '';
          this.password = '';
          
          event.preventDefault();
        },
        login(email, password) {
    
        }
      },
      mounted() {
        if (!this.user)
          return;
    
        console.log('Writing to session storage...');
        sessionStorage.setItem('user', JSON.stringify(user));
      }
    })
    
    var app = new Vue({
      el: '#app'
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <sign-in></sign-in>
    </div>