Can the color of an icon be altered by selecting a list item in VueJS?

I am currently working on a VueJS Dropdown Menu implementation that involves displaying an icon. When this icon is clicked, a Dropdown Menu containing 3 other icons should appear. Furthermore, upon clicking one of these icons, I intend for the original Dropdown Menu icon to change as well. While I have successfully accomplished most of this functionality, there seems to be an issue with dynamically changing the color of the icon (one green, one grey, one red) due to what I suspect is Vue's limitation in setting colors via variables.

Below is the code snippet for the menu:

<v-card outlined>
    <v-card-title>Selection</v-card-title>

    <v-toolbar height="80" elevation="0">
        <v-menu
            transition="slide-y-transition"
            nudge-left="9"
            nudge-bottom="10"
            offset-y>

            <template v-slot:activator="{ on: menu }">
                <v-tooltip right>
                    <template v-slot:activator="{ on:tooltip }">
                        <v-btn class="mb-6" v-on="{...tooltip, ...menu}" fab>
                            <v-icon x-large>{{ myIcon }}</v-icon>
                        </v-btn>
                    </template>
                    <span>Steady</span>
                </v-tooltip>
            </template>


            <v-list>
                <v-list-item>
                    <v-icon color="green" x-large @click="changeSupplierStatusToUp()">mdi-chevron-up</v-icon>
                </v-list-item>

                <v-divider></v-divider>

                <v-list-item>
                    <v-icon color="grey" x-large @click="changeSupplierStatusToMid()">mdi-unfold-less-vertical</v-icon>
                </v-list-item>

                <v-divider></v-divider>

                <v-list-item>
                    <v-icon color="red" x-large @click="changeSupplierStatusToDown()">mdi-chevron-down</v-icon>
                </v-list-item>
            </v-list>
        </v-menu>
    </v-toolbar>
</v-card>

Additionally, here is the relevant JavaScript code:

<script>
export default {
    name: "Selection",
    data() {
        return {
            myIcon: 'mdi-unfold-less-vertical',
        }
    },
    props: {},
    computed: {},
    methods: {
        changeSupplierStatusToUp() {
            this.myIcon = 'mdi-chevron-up'
        },
        changeSupplierStatusToDown() {
            this.myIcon = 'mdi-chevron-down'
        },
        changeSupplierStatusToMid() {
            this.myIcon = 'mdi-unfold-less-vertical'
        }
    }
}
</script>

<style scoped></style>

Your assistance in resolving this issue would be greatly appreciated. :-)

Answer №1

To achieve consistency in icon color, assign the color to a variable and adjust it as needed within your functions.

An effective approach is transforming myIcon into an Object with properties like name and color.

I opted for storing colors as part of an Object for convenient selection.

Subsequently, I linked the color of each v-icon to correspond to the relevant property within the colors Object.

Within the click event for each icon, modify both myIcon.name and myIcon.color.

For example:

changeSupplierStatusToUp() {
  this.myIcon.name = 'mdi-chevron-up';
  this.myIcon.color = this.colors.green;
}

Remember to prefix the color property with a colon (:) to enable reactivity and use a variable instead of plain text --

<v-icon :color="colors.green" ...>
.

Finally, within your activator icon:

<v-icon x-large :color="myIcon.color">{{ myIcon.name }}</v-icon>
.

/* Vue instance and data setup */
const app = new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  name: "Selection",
  data() {
    return {      
      myIcon: {
        name: 'mdi-unfold-less-vertical',
        color: 'default'
      },
      colors: {
        green: 'green',
        grey: 'grey',
        red: 'red'
      }
    }
  },
  props: {},
  computed: {
    
  },
  methods: {
    changeSupplierStatusToUp() {
      this.myIcon.name = 'mdi-chevron-up';
      this.myIcon.color = this.colors.green;
    },
    changeSupplierStatusToDown() {
      this.myIcon.name = 'mdi-chevron-down';
      this.myIcon.color = this.colors.red;
    },
    changeSupplierStatusToMid() {
      this.myIcon.name = 'mdi-unfold-less-vertical';
      this.myIcon.color = this.colors.grey;
    }
  }
});
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e197948495888798a1d3cf99">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/@mdi/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abcdc4c5dfeb9f85d3">[email protected]</a>/css/materialdesignicons.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e585b4b6e1c0056">[email protected]</a>/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e585b4b5a4748576e1c0056">[email protected]</a>/dist/vuetify.js"></script>

<div id="app">
  <v-app>
    <v-card outlined>
      <v-card-title>Selection</v-card-title>
        <v-toolbar height="80" elevation="0">
          <v-menu
            transition="slide-y-transition"
            nudge-left="9"
            nudge-bottom="10"
            offset-y
          >
            <template v-slot:activator="{ on: menu }">
              <v-tooltip right>
                <template v-slot:activator="{ on:tooltip }">
                  <v-btn class="mb-6" v-on="{...tooltip, ...menu}" fab>
                    <v-icon
                      x-large
                      :color="myIcon.color"
                    >{{ myIcon.name }}</v-icon>
                  </v-btn>
                </template>
                <span>Steady</span>
              </v-tooltip>
            </template>

            <v-list>
              <v-list-item>
                <v-icon
                  x-large
                  :color="colors.green"
                  @click="changeSupplierStatusToUp()"
                >mdi-chevron-up</v-icon>
              </v-list-item>
              <v-divider></v-divider>
              <v-list-item>
                <v-icon 
                 x-large
                :color="colors.grey"
                @click="changeSupplierStatusToMid()"
              >mdi-unfold-less-vertical</v-icon>
              </v-list-item>
                <v-divider></v-divider>
              <v-list-item>
                <v-icon
                  x-large
                  :color="colors.red"
                  @click="changeSupplierStatusToDown()"
                >mdi-chevron-down</v-icon>
              </v-list-item>
            </v-list>
        </v-menu>
      </v-toolbar>
    </v-card>
  </v-app>
</div>

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

Setting the borderRadius for a web view on Android Maps V3: A complete guide

In my application, I am using Android Map V3 and have encountered a bug specific to the Kit-Kat version. The chromium kit throws up an error message - nativeOnDraw failed; clearing to background color, which prevents the map from being displayed. Despite ...

Remove the underline from links in gatsbyjs

When comparing the links on (check source code https://github.com/gatsbyjs/gatsby/tree/master/examples/using-remark), they appear without an underline. However, on my blog (source code here: https://github.com/YikSanChan/yiksanchan.com), all links are un ...

Guide to utilizing axios.request(config) in Vue.js

I have been attempting to use Axios in my vue.js project to make HTTP requests. Despite reviewing the Axios documentation on GitHub and exploring various examples online, I have yet to find a solution. My goal is to create a configuration file where I can ...

What are the best tools to develop a browser-based 2D top-down soccer simulation?

I'm looking to create a 2D top-down soccer simulation game for web browsers using modern technologies and without the need for additional plugins like Flash or Silverlight, making it compatible with mobile devices as well. The game will be AI-controll ...

The CSS transition fails to function correctly when rendering a React element within an array

When rendering a React component within an array using CSS transitions, I noticed that the elements in the array re-order and change style. Surprisingly, only the elements moving up have transitions applied, while the ones moving down do not. I expect all ...

What is the widely used term for the container that allows for panning by dragging with a mouse?

I am looking to design a container that extends beyond the width of the page, allowing users to pan by dragging through empty space between controls without zooming in or out. What is this type of container control typically referred to as? I am intereste ...

Implementing basic authentication in Socket.IO on a Node.js server

Currently, I am attempting to develop a basic websocket client for establishing a connection with a device. However, the device requires both a username and password for authentication purposes, posing a challenge for me as I struggle to figure out how to ...

What is the best way to select an element with a dynamic ID in jQuery?

I'm encountering an issue when passing the ID through a directive. I'm unable to access the element using jQuery within the Link function, even though the element is receiving the correct dynamic ID as a parameter: Here's the Directive: (f ...

Adding VueJS to the main div and content submitted by users

I am in the process of creating a compact guide website where users can submit articles related to a specific game. The website incorporates various components written in Javascript using VueJS. While most of the website is powered by Laravel and rendered ...

Displaying radio values in an Angular ng-repeat directive

I am new to Angular and facing difficulties in capturing the selected radio value when using ng-repeat. The documentation is a bit unclear on this matter. Any assistance or guidance would be highly appreciated. <div ng-repeat="item in ed"> <lab ...

JavaScript is not designed to run a second time

Currently, I have a script set up using $(document).ready(). It works perfectly upon initial loading. However, I also need this script to execute whenever the user changes an HTML select control. Ideally, upon page load, I want the filter and sort functio ...

What are the reasons for passing a global variable to a function?

Is there a difference between the two ways of writing this code? First Method: (function(i) { // Manipulate i here }(global_variable)) Second Method: (function() { // Manipulate global_variable here }()) What's the reason for passing a gl ...

Resetting the selected value in an Angular2 select element after the user makes a change

I have a dropdown menu which the user can select an option from. Initially it has a default value and when the user makes a new selection, I need to ask for confirmation by showing a message "are you sure?". If the answer is NO, then I should revert back t ...

Having issues with accessing data from Informix database in PHP due to an undefined index?

I am encountering the following error multiple times per row: Notice: Undefined index: enviopre in /opt/lampp/htdocs/pruebax/pruebaxone.php on line 34 Notice: Undefined index: enviofra in /opt/lampp/htdocs/pruebax/pruebaxone.php on line 35 Notice: Undef ...

The connection to sockjs-node was refused due to a network error

After setting up a new small web application using vue cli, I encountered an issue right from the start. Here is the error message: (base) marco@pc:~/vueMatters/testproject$ npm run serve > <a href="/cdn-cgi/l/email-protection" class="__cf_email__ ...

Why won't Node.js let me redirect to my error page?

I've been putting together my newsletter project with the Mailchimp API, everything seems to be working fine except for when I try to redirect to a failure page if the status code is not 200. The browser shows an error message saying 'localhost r ...

What is the best way to create a sequential number pattern of 1, 2, 3, 4 in Mongoose?

Is there a way to create a similar pattern without coding experience? I'm not familiar with coding, so looking for guidance. Here is the code snippet in question: array = 1,2,3,4,5 const note = new notedModel ({ _id: array, note: args[1] ...

Issue with Fancybox and Jquery compatibility

I'm encountering some issues with conflicting Javascripts. One script is responsible for creating a dropdown menu, while another set of scripts enable fancybox functionality. However, having both sets of scripts in the header code results in conflicts ...

Guide to passing arguments to a function within Vue's v-for loop?

Is there a way to pass the parameter {{ item.id }} to my function productos.mostrarModal() within a v-for loop in vue.js? <div v-for="item of articulos"> <a href="#" onclick="productos.mostrarModal()" > <h2>{{item.name}}< ...

What is the correct method for closing a style element in Nextjs JSX?

Having trouble adding some unique styling to a jsx component. The code snippet below is throwing an error when compiled. import Card from "./card"; export default function CardRow(){ return( <> <div> <Card> ...