applying conditional rendering in vue.js

I'm currently working on developing a chat application using the guidelines outlined in this tutorial: https://socket.io/get-started/private-messaging-part-1/

One of my goals is to customize the appearance of the messages, so that when a message is sent by the user, it will have a grey background instead of the default white.

The challenge I am facing right now is that all messages are assigned the same CSS class (message), which makes it difficult to apply conditional styling. Is there a way to implement conditional styling based on the sender?

In the template section of the code:

    <ul class="messages">
      <li
        v-for="(message, index) in user.messages"
        :key="index"
        class="message"
      >
        <div v-if="displaySender(message, index)" class="sender">
          {{ message.fromSelf ? "(yourself)" : user.username }}
        </div>
        {{ message.content }}
      </li>
    </ul>

In the style section of the code:

.message {
  list-style: none;
  background-color: white;
  
  border: solid;
  border-color: gray;
  border-width: 1px;
  border-radius: 15px;

  margin-bottom: 10px;
  padding: 10px;
}

Answer №1

Develop a custom class, :class=..., that is determined by the status of message.fromSelf, and apply styling to the HTML element based on the class.

For instance, if we establish a custom class,

:class="message.fromSelf ? 'self-message' : ''"

Alternatively (credit goes to recommendation from Wittgenstein)

:class="{ 'self-message': message.fromSelf }"

and then define styles for it:

.self-message {
    background-color: gray;
}

The outcome will be like this:

https://i.sstatic.net/wmF6i.jpg

A small operational example program:

<script>
import { ref } from "vue";

export default {
  data() {
    return {
      messages: [
        {
          fromSelf: true,
          content: "Hello folks!",
          username: ''
        },
        {
          fromSelf: false,
          content: "Hello, back to you!",
          username: 'John'
        },
        {
          fromSelf: true,
          content: "How are you doing?",
          username: ''
        },
        {
          fromSelf: false,
          content: "I'm doing very well here, you?",
          username: 'John'
        },
      ],
    };
  },
};
</script>

<template>
  <ul class="messages">
    <li
      v-for="(message, index) in messages"
      :key="index"
      :class="{ 'self-message': message.fromSelf, 'message': true }"
    >
      <div class="sender">
        {{ message.fromSelf ? "(yourself)" : message.username + ":" }}
      </div>
      {{ message.content }}
    </li>
  </ul>
</template>

<style>
.message {
  list-style: none;
  background-color: white;
  
  border: solid;
  border-color: gray;
  border-width: 1px;
  border-radius: 15px;

  margin-bottom: 10px;
  padding: 10px;
}
  
.self-message {
  background-color: lightgray;
}
</style>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Image placed as background for registration form

In my Vue project, I am trying to create a login form with an image as the background. However, I am facing an issue where the image is not displaying on the page. Can someone guide me on how to add a picture behind the form? HTML: Below is the HTML code ...

What is the best way to use CSS to center two blocks with space in between them?

My goal is to achieve a specific design: I want two text blocks with some space in between them aligned around the midline of the page (refer to the image). I have experimented with the float property, as well as used margin and padding to create the gap ...

Trigger the opening of a class or window upon pressing the button

Good evening, I'm attempting to create a functionality where pressing a specific button will open a window. However, I am unsure of how to achieve this using CSS classes. My initial thought was to add a new class in the CSS file and call it every ti ...

vue-dropzone fails to create thumbnails when a file is added

I am facing an issue where I want to upload files that are already stored on my server to the Dropzone. Despite searching extensively through both vue-dropzone and regular dropzone documentation, as well as various GitHub issues for solutions, I have not b ...

What strategies and techniques should be considered when creating websites optimized for mobile devices?

With a wealth of experience in programming languages like Java, Python, and C, I actively engage in self-study to enhance my skills. While I have dabbled in creating mobile-friendly websites, upon reviewing my work, it is evident that my frontend developme ...

Why am I restricted to adjusting mat-elevation settings within the component's CSS exclusively?

In my Angular 8 project, I am utilizing Angular material to enhance the design of my material cards. To set up the shadow effect on these cards, I am using the elevation helper mixins provided in the documentation: https://material.angular.io/guide/elevati ...

Let's talk about the CSS properties for centering content and automatically

I've been struggling with getting my navbar to center and adjust its width based on the content inside. Can anyone help me with this? <nav> <ul id="menu" class="black"> <li><a href="index.html">Home</a></l ...

Cannot designate Vue setup function as asynchronous

I have a Vue3 application using the composition api and I am trying to fetch data asynchronously within the setup function. Here are two approaches that have successfully worked for me: Approach 1: Working with Promises <template> <div ...

Vuejs Emailjs Vee-validate TypeError: Unable to access property 'target' as it is undefined

I've encountered an issue with validating and sending my data using emailjs and vee-validate. It seems to work fine without vee-validate. Can anyone assist me with this problem? Thank you. Software Versions: vee-validate: 3.4.5 vue: 2.6.6 emailjs: & ...

Ensuring the aspect ratio of images stays consistent within a flexbox using CSS

How can I create a grid of images without any spacing in between them? I want the width to be 100% of the parent element and each column to have the same size, for example, 20%. Using flex takes care of the columns, but I'm struggling with making the ...

Could a javascript loop be created to continuously activate a button with each iteration?

I have just started learning javascript and I am in the process of creating a website where users can change the background by simply clicking on a button. It's working perfectly fine so far, but I want to add another feature where the background imag ...

When utilizing state in ReactJS to modify the color of my button, the change does not take effect on the first click. How can I troub

Whenever I click the button that routes to different locations via an API, the route works fine but the button color doesn't change on the first click. To address this issue, I implemented the useState hook and CSS to dynamically change the button co ...

Guide on how to fetch Laravel's CSRF token with a separate Vue frontend

Is it possible to transfer the Laravel csrf token to Vue when the backend and frontend are located in separate directories and subdomains? I am working on an application that requires a distinct separation between the backend and frontend for organizationa ...

Which one to choose for creating a Kahoot-like app: Laravel Sanctum or Passport?

Excited about creating a game-app similar to kahoot for some fun! :) This app will allow users to either sign up and host a game or simply join one with a PIN. Players can then challenge themselves by answering various questions. The plan is to develop a ...

Unspecified error encountered in the VUE selection view

I am facing an issue with the undefined value in the select view while attempting to add a new project. Could you suggest a solution? I tried using v-if but it didn't work for me. This is how my code looks: <v-select v-model="pro ...

I struggle with managing a z-index in conjunction with an absolute position

Check out this codesandbox to see the issue where the 3 dots button is displayed over the menu. Click on the 3 dots to understand the problem. Below is the CSS code for the menu: .more-menu { position: absolute; top: 100%; z-index: 900; float: l ...

Adjust the navigation text and logo color as you scroll on the page

I am new to HTML and CSS and I am working on a website with PagePiling.js scrolling feature. I want to change the color of my logo image and navigation text dynamically as I scroll to the next section. Specifically, I only want the part of the logo and tex ...

Scaling images using jQuery for enhanced visual appeal

I implemented a jQuery hover effect on my image gallery where the images have a default size of 265 x 172 and are displayed horizontally. My goal is to have the images swap out for larger ones sized at 449 x 223 when a user hovers over them. However, I wan ...

Guide: Initiating an action in NuxtJs

I am attempting to trigger an action in my Vue component from my Vuex store. Below is the content of my aliments.js file in the store: import Vue from 'vue'; import Vuex from 'vuex'; import axios from 'axios'; Vue.use(Vuex, ...

Incorporating a CNAME into Your Vue.js Project

I've been working on a Vue.js project using the vue cli tool and I wanted to add a CNAME file to deploy it in the root folder. The project is hosted on gh-pages, but I've been struggling to include the CNAME file correctly in my gh-pages branch. ...