Open In App

Checkout Form Using Tailwind.css & Vue.js

Last Updated : 01 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In modern web development, creating user-friendly and visually appealing forms is essential, especially for tasks like online purchases. In this article, we’ll guide you through building a checkout form using two popular technologies: Tailwind CSS for styling and Vue.js for dynamic behaviour.

Output Preview:

Screenshot-2024-04-23-155009

Prerequisites:

Approach

  • Initialize a new Vue.js project and install Tailwind CSS and its dependencies.
  • Create a Vue.js component named CheckoutForm.vue to contain the form.
  • Structure the form with HTML, including sections for billing address and payment details.
  • Define data properties to store form values and methods to handle form submission and interactions.
  • Prevent default form submission with @submit.prevent and handle submission in a method, updating the submitted property.
  • Use Tailwind CSS utility classes to style the form components for a clean and responsive layout.

Steps to Create the Application

Step 1: Create the Vue project using the following command:

npx @vue/cli create checkout-form

Step 2: Now follow the provided instructions and get into the project directory:

cd checkout-form

Step 3: Install the necessary packages/libraries in your project using the following commands.

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwindcss init -p

Project Structure:

Screenshot-from-2024-04-21-15-42-32

Project Structure

The updated dependencies in package.json file will look like:

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "autoprefixer": "^10.4.19",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "postcss": "^8.4.38",
    "tailwindcss": "^3.4.3"
  }

Example: Implementation to design the checkout form

HTML
<!-- src/components/CheckoutForm.vue -->

<template>
    <div id="app" 
         class="container mx-auto py-8 px-4">
        <h1 class="text-3xl font-bold 
                   mb-8 text-center">
          Checkout Form
          </h1>
        <form @submit.prevent="submitForm" 
              class="max-w-lg mx-auto bg-white
                     p-8 rounded-lg shadow-md">
            <!-- Billing Address -->
            <div>
                <div class="text-2xl my-4">
                      Billing Address
                  </div>
                <div class="grid grid-cols-1 
                            md:grid-cols-2 gap-4">
                    <div class="mb-4">
                        <label for="firstName" 
                               class="block text-gray-700 mb-2">
                              First Name
                          </label>
                        <input v-model="formData.firstName" 
                               type="text" id="firstName" 
                               name="firstName" 
                               class="w-full form-input p-1 
                                      border rounded-md 
                                      shadow-sm" required>
                    </div>
                    <div class="mb-4">
                        <label for="lastName" 
                               class="block text-gray-700 mb-2">
                              Last Name
                          </label>
                        <input v-model="formData.lastName" 
                               type="text" id="lastName" name="lastName" 
                               class="w-full form-input p-1 border 
                                      rounded-md shadow-sm" required>
                    </div>
                </div>
                <div class="mb-4">
                    <label for="email" 
                           class="block text-gray-700 mb-2">
                          Email Address
                      </label>
                    <input v-model="formData.email" 
                           type="email" id="email" name="email" 
                           class="w-full form-input p-1 border 
                                  rounded-md shadow-sm" required>
                </div>
                <div class="mb-4">
                    <label for="address" 
                           class="block text-gray-700 mb-2">
                          Address
                      </label>
                    <textarea v-model="formData.address" 
                              id="address" name="address" rows="5" 
                              class="w-full form-textarea p-1 border 
                                     rounded-md shadow-sm" required>
                      </textarea>
                </div>
                <div class="mb-4 grid grid-cols-1 
                            md:grid-cols-3 gap-4">
                    <div>
                        <label for="city" 
                               class="block text-gray-700 mb-2">
                              City
                          </label>
                        <input v-model="formData.city" 
                               type="text" id="city" name="city" 
                               class="w-full form-input p-1 border 
                                      rounded-md shadow-sm" required>
                    </div>
                    <div>
                        <label for="zip" 
                               class="block text-gray-700 mb-2">
                              ZIP Code
                          </label>
                        <input v-model="formData.zip" 
                               type="text" id="zip" name="zip" 
                               class="w-full form-input p-1 border 
                                      rounded-md shadow-sm" required>
                    </div>
                    <div>
                        <label for="country" 
                               class="block text-gray-700 mb-2">
                              Country
                          </label>
                        <input v-model="formData.country" 
                               type="text" id="country" name="country" 
                               class="w-full form-input p-1 border 
                                      rounded-md shadow-sm" required>
                    </div>
                </div>
                <div class="mb-4">
                    <input v-model="sameAsBilling" 
                           type="checkbox" 
                           @change="toggleShippingAddress"/>
                    <label class="ml-2">
                          Shipping address is the 
                          same as my billing address
                      </label>
                </div>
                <div class="mb-8">
                    <input v-model="saveInfo" type="checkbox"/>
                    <label class="ml-2">
                          Save this information 
                          for next time
                      </label>
                </div>
            </div>
            <!-- Payment -->
            <div class="text-2xl mb-4">
                  Payment
              </div>
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div class="mb-4">
                    <label for="nameOnCard" 
                           class="block text-gray-700 mb-2">
                          Name on Card
                      </label>
                    <input v-model="formData.nameOnCard" 
                           type="text" id="nameOnCard" 
                           name="nameOnCard" 
                           class="w-full form-input p-1 border 
                                  rounded-md shadow-sm" required>
                </div>
                <div class="mb-4">
                    <label for="cardNumber" 
                           class="block text-gray-700 mb-2">
                          Card Number
                    </label>
                    <input v-model="formData.cardNumber" 
                           type="text" id="cardNumber" name="cardNumber" 
                           class="w-full form-input p-1 
                                  border rounded-md 
                                  shadow-sm" required>
                </div>
            </div>
            <div class="grid grid-cols-2 
                        md:grid-cols-4 gap-4">
                <div class="mb-4">
                    <label for="expiration" 
                           class="block text-gray-700 mb-2">
                          Expiration
                    </label>
                    <input v-model="formData.expiration" 
                           type="text" id="expiration" name="expiration" 
                           class="w-full form-input p-1 
                                  border rounded-md shadow-sm" required>
                </div>
                <div class="mb-4">
                    <label for="cvv" 
                           class="block text-gray-700 mb-2">
                          CVV
                      </label>
                    <input v-model="formData.cvv" type="text" 
                           id="cvv" name="cvv" 
                           class="w-full form-input p-1 border 
                                  rounded-md shadow-sm" required>
                </div>
            </div>
            <button type="submit" 
                    class="mt-8 w-full bg-green-500 
                           hover:bg-green-700 text-white 
                           font-bold py-2 px-4 rounded">
                  Continue to Checkout
              </button>
        </form>

        <!-- Display submitted data -->
        <div v-if="submitted" 
             class="fixed inset-0 flex 
                    items-center justify-center">
            <div class="bg-white p-8 rounded-lg shadow-md">
                <h2 class="text-xl font-bold mb-4">
                      Successfully Checked Out!
                  </h2>
                <p>
                      Your order has been 
                      processed successfully.
                  </p>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                formData: {
                    firstName: '',
                    lastName: '',
                    email: '',
                    address: '',
                    city: '',
                    zip: '',
                    country: '',
                    nameOnCard: '',
                    cardNumber: '',
                    expiration: '',
                    cvv: ''
                },
                sameAsBilling: false,
                saveInfo: false,
                submitted: false,
                submittedData: {}
            };
        },
        methods: {
            submitForm() {
                this.submitted = true;
                // Your form submission logic goes here
                setTimeout(() => {
                  // Close dialog box after a short delay
                    this.submitted = false; 
                  // Close dialog box after 3 seconds 
                  // (adjust the time as needed)
                }, 3000); 
            },
            toggleShippingAddress() {
                if (this.sameAsBilling) {
                    this.formData.shippingAddress = 
                          this.formData.address;
                } else {
                    this.formData.shippingAddress = {};
                }
            }
        }
    };
</script>
HTML
<!-- src/App.vue -->

<template>
  <div id="app" class="bg-gray-100">
    <CheckoutForm />
  </div>
</template>

<script>
import CheckoutForm from './components/CheckoutForm.vue';
import "./assets/main.css";

export default {
  name: 'App',
  components: {
    CheckoutForm
  }
};
</script>
CSS
/* src/assets/main.css */

@tailwind base;
@tailwind components;
@tailwind utilities;
JavaScript
// tailwind.config.js

module.exports = {
  content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

Step to Run Application: Run the application using the following command from the root directory of the project

npm run serve

Output: Your project will be shown in the URL http://localhost:8080/

checkout form using vue.js





Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads