software development

Build A Chat App Using Html Css Vue Js

This article provides a guide to building a chat application using HTML, CSS, and the Vue.js framework, along with the Vuetify.js library for a polished user interface. Vue.js, created by Evan You in 2011, is a popular JavaScript framework for developing fast and efficient single-page applications.

Setting Up Your Project and Layout

First, create a project folder, for instance, named chat-app. Inside this folder, create an index.html file, which will serve as the main template for your application.

Your index.html file will contain the basic structure for your chat application. Below is a simplified example of how your HTML might begin, focusing on the root element for your Vue app:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat App</title>
    <link rel="stylesheet" href="style.css">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
    <div id="app">
        </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.js"></script>
    <script src="main.js"></script>
</body>
</html>

Step 1: Create a Vue Instance

The first step in your main.js file is to create a new Vue instance. This instance will mount to the #app element in your index.html file and control your application’s data and behavior.

// main.js

new Vue({
    el: '#app', // Mount to the element with id 'app'
    vuetify: new Vuetify(), // Initialize Vuetify
    data: {
        message: 'Welcome to the chat app!',
        // Other data properties for your chat app
    },
    methods: {
        // Your methods will go here
    },
    // Add other Vue options like components, computed properties, etc.
});

Step 2: Add an Input Field for Messages

To allow users to type and send messages, you’ll add an input field. Within your Vue template (or a component), you can use a textarea or a Vuetify v-text-field component. You’ll also need to bind its value to a data property using v-model.

<template>
    <v-container>
        <v-text-field
            label="Type your message"
            v-model="newMessage"
            @keydown.enter="sendMessage"
            outlined
            clearable
        ></v-text-field>
    </v-container>
</template>

<script>
export default {
    data() {
        return {
            newMessage: '',
        };
    },
    methods: {
        sendMessage() {
            // Logic to send the message will go here
            console.log('Sending message:', this.newMessage);
            this.newMessage = ''; // Clear the input field after sending
        }
    }
}
</script>

Explanation:

  • v-model="newMessage" creates a two-way data binding, connecting the input field’s value to the newMessage data property.
  • @keydown.enter="sendMessage" calls the sendMessage method when the Enter key is pressed within the input field.

Step 3: Create a Method for Sending Messages

You’ll need a method to handle sending messages, typically involving an API call to a backend. For this, you can use the Axios library for making HTTP requests. First, install Axios:

npm install axios

Then, integrate it into your Vue application:

// main.js or within a component's methods

import axios from 'axios';

new Vue({
    el: '#app',
    vuetify: new Vuetify(),
    data: {
        newMessage: '',
        messages: [], // Array to store messages
    },
    methods: {
        async sendMessage() {
            if (this.newMessage.trim() === '') return; // Don't send empty messages

            try {
                // Replace with your actual API endpoint
                const response = await axios.post(process.env.VUE_APP_SEND_MESSAGE_API_URL, {
                    text: this.newMessage,
                    // Add other message properties like sender, timestamp, etc.
                });
                console.log('Message sent:', response.data);
                this.messages.push(response.data); // Add the sent message to the local list
                this.newMessage = ''; // Clear the input field
            } catch (error) {
                console.error('Error sending message:', error);
                // Handle error (e.g., show a notification)
            }
        },
        // Other methods
    },
});

Explanation:

  • The sendMessage method is marked async because it will perform an asynchronous operation (the API call).
  • axios.post() sends a POST request to your specified API endpoint.
  • process.env.VUE_APP_SEND_MESSAGE_API_URL is used for environment variables, making your API endpoint configurable.

Step 4: Receive Messages from Your Friends

To make your chat app interactive, you’ll need to fetch messages from your backend. This can be done by making an API call and updating your messages array. You might use mounted() lifecycle hook to fetch initial messages or set up a polling mechanism to fetch new messages periodically.

// main.js or within a component

new Vue({
    // ... (previous setup)
    data: {
        newMessage: '',
        messages: [],
    },
    methods: {
        // ... (sendMessage method)

        async fetchMessages() {
            try {
                // Replace with your actual API endpoint to fetch messages
                const response = await axios.get(process.env.VUE_APP_GET_MESSAGES_API_URL);
                this.messages = response.data; // Update the messages array
            } catch (error) {
                console.error('Error fetching messages:', error);
            }
        },
    },
    mounted() {
        // Fetch messages when the component is mounted
        this.fetchMessages();
        // You might also set up an interval to poll for new messages
        // setInterval(this.fetchMessages, 5000); // Fetch every 5 seconds
    }
});

Step 5: Add Support for Multiple Users

To display messages from different users, you’ll iterate over your messages array and dynamically render each message, including sender information. Vue’s v-for directive is perfect for this.

<template>
    <v-container>
        <v-card class="mb-4" v-for="message in messages" :key="message.id">
            <v-card-title>{{ message.sender }}</v-card-title>
            <v-card-text>{{ message.text }}</v-card-text>
            <v-card-subtitle>{{ new Date(message.timestamp).toLocaleString() }}</v-card-subtitle>
        </v-card>

        <v-text-field
            label="Type your message"
            v-model="newMessage"
            @keydown.enter="sendMessage"
            outlined
            clearable
        ></v-text-field>
    </v-container>
</template>

<script>
export default {
    data() {
        return {
            newMessage: '',
            messages: [
                // Example messages (will be replaced by fetched data)
                { id: 1, sender: 'Alice', text: 'Hey there!', timestamp: Date.now() - 60000 },
                { id: 2, sender: 'Bob', text: 'Hi Alice!', timestamp: Date.now() - 30000 },
            ],
        };
    },
    methods: {
        sendMessage() { /* ... */ },
        fetchMessages() { /* ... */ }
    },
    mounted() { /* ... */ }
}
</script>

Explanation:

  • v-for="message in messages" loops through each message object in the messages array.
  • :key="message.id" is crucial for Vue’s rendering performance and helps track each item’s identity.
  • You’ll typically display message.sender, message.text, and message.timestamp (or other relevant properties).

Step 6: Show the List of Online Users

To display a list of online users, you can maintain an array of active users in your Vue instance’s data. You might fetch this list from your backend using an API call. For routing between different views (e.g., a chat view and a user list view), you’d typically use Vue Router.

First, install Vue Router:

npm install vue-router

Then, set it up in your main.js:

// main.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue'; // Your main App component
import ChatView from './views/ChatView.vue'; // Example chat view
import UserListView from './views/UserListView.vue'; // Example user list view

Vue.use(VueRouter);

const routes = [
    { path: '/', component: ChatView },
    { path: '/users', component: UserListView },
];

const router = new VueRouter({
    routes,
    mode: 'history', // Use history mode for clean URLs
});

new Vue({
    router,
    vuetify: new Vuetify(),
    render: h => h(App), // Render your main App component
}).$mount('#app');

Then, in your UserListView.vue component, you would fetch and display the online users:

<template>
    <v-container>
        <h2>Online Users</h2>
        <v-list dense>
            <v-list-item v-for="user in onlineUsers" :key="user.id">
                <v-list-item-content>
                    <v-list-item-title>{{ user.name }}</v-list-item-title>
                </v-list-item-content>
            </v-list-item>
        </v-list>
    </v-container>
</template>

<script>
import axios from 'axios';

export default {
    data() {
        return {
            onlineUsers: [],
        };
    },
    methods: {
        async fetchOnlineUsers() {
            try {
                const response = await axios.get(process.env.VUE_APP_ONLINE_USERS_API_URL);
                this.onlineUsers = response.data;
            } catch (error) {
                console.error('Error fetching online users:', error);
            }
        },
    },
    mounted() {
        this.fetchOnlineUsers();
        // You might also set up a polling mechanism here for real-time updates
    },
};
</script>

Step 7: Designing with CSS

You have two primary ways to style your application: inline CSS or external CSS files. For better maintainability and organization, especially with Vue.js, using external CSS files is recommended. With Vuetify, many styles are already provided.

/* style.css */
body {
    font-family: 'Roboto', sans-serif;
    margin: 0;
    background-color: #f5f5f5;
}

#app {
    max-width: 900px;
    margin: 20px auto;
    background-color: #ffffff;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.v-card {
    margin-bottom: 15px;
}

/* Add more custom styles as needed */

Link this file in your index.html as shown in the “Setting Up Your Project and Layout” section.

Inline CSS (Generally discouraged for large applications):

You can apply inline styles using the style attribute directly in your HTML elements. However, for a Vue.js application, it’s often more efficient to use component-scoped CSS (using <style scoped> in .vue files) or global CSS files.

Conclusion

This tutorial provided a foundational understanding of building a chat application using Vue.js, HTML, CSS, and Vuetify. You’ve learned how to set up your project, create a Vue instance, handle user input, send and receive messages, and display dynamic lists of users and messages.

For the complete code and further development, you can explore the provided resources or contact for a custom Vue.js chat room build. Remember that a full-fledged chat application will also require a robust backend for message storage, user authentication, and real-time communication (e.g., WebSockets).

If you have any questions or are interested in custom application development, feel free to contact us!

Contact Us

We will add your info to our CRM for contacting you regarding your request. For more details, please review our privacy policy.