Is there a smarter approach in Vue.js to selectively add classes?

Within my Vue instance, I have implemented a method that conditionally generates HTML markup based on specific conditions. Although the markup remains the same for each scenario, only different styles are applied.

I am curious if there is a more elegant approach to achieve this. Should I opt for a method, computed property, or component? If a computed property is recommended, how can I pass the value for evaluation?

Does anyone know of an alternative solution?

<div v-for="item in items">
    <div v-if="!_.isEmpty(item.files)">
        <ul>
            <li v-for="file in item.files">
                <span v-html="fileIcon(file.fileExtension)"></span>
            </li>
        </ul>
   </div>
</div>

var vm = new Vue({
    el: '#root',
    data: {
       items: [
           {
              "id": 126,
              "content": "blah...",
              "files": [
                   {
                      "id": 8,
                      "filename": "test.doc",
                      "fileExtension": "doc"
                   }
               ]
            },
            {
              "id": 127,
              "content": "blah...",
              "files": []
            }
        ]
     },
     methods: {
        fileIcon: function (extension) {
            var str;
            switch (extension) {
                case "jpg":
                case "jpeg":
                case "png":
                case "gif":
                    str = "<i class='fa fa-file-image-o file-picture'></i>";
                    break;
                case "pdf":
                    str = "<i class='fa fa-file-pdf-o file-pdf' ></i>";
                    break;
                case "xls":
                case "xlsx":
                    str = "<i class='fa fa-file-excel-o file-excel' ></i>";
                    break;
                case "doc":
                case "docx":
                    str = "<i class='fa fa-file-word-o file-word' ></i>";
                    break;
                default:
                    str = "<i class='fa fa-file-file-o file-empty' ></i>";
                    break;
            }

            return str;
        }
     }
});

I'm relatively new to Vue, so any guidance with code snippets would be greatly appreciated.

Answer №1

Utilizing v-html might not be the best approach for this situation.

The key is to establish a mapping of types to classes

Begin by defining the object

let fileTypes = {
  jpg: ['fa-file-image-o', 'file-picture'],
  jpeg: ['fa-file-image-o', 'file-picture'],
  png: ['fa-file-image-o', 'file-picture'],
  gif: ['fa-file-image-o', 'file-picture'],
  pdf: ['fa-file-pdf-o', 'file-pdf'],
  xls: ['fa-file-excel-o', 'file-excel'],
  xlsx: ['fa-file-excel-o', 'file-excel'],
  doc: ['fa-file-word-o', 'file-word'],
  docx: ['fa-file-word-o', 'file-word']
}

Create a function

determineFileType (type) {
  return fileTypes[type] || ['fa-file-file-o', 'file-empty']
}

Then, include it within the template

<span :class="determineFileType(file.fileExtension)">

Answer №2

To make your code more organized, consider utilizing methods that return classes. Check out this example on CodePen:

CodePen Example

For further information on this topic, refer to: Vue.js Documentation

It's recommended to include file types and their respective classes in the 'data' section as well. This approach can simplify the method implementation.

 var vm =  new Vue({
        el: '#app',
        data: {
           items: [
                    {
                      "id": 126,
                      "content": "blah...",
                      "files": [
                           {
                              "id": 8,
                              "filename": "test.doc",
                              "fileExtension": "doc"
                           }
                       ]
                    },
                    {
                      "id": 127,
                      "content": "blah...",
                      "files": []
                    }
            ]
         },
         methods: {
            fileIcon: function (file) {
              
              var ext = file.fileExtension;
              

                var str;

                switch (ext)
                {
                    case "jpg":
                    case "jpeg":
                    case "png":
                    case "gif":
                        str = "fa fa-file-image-o file-picture";
                        break;
                    case "pdf":
                        str = "fa fa-file-pdf-o file-pdf";
                        break;
                    case "xls":
                    case "xlsx":
                        str = "fa fa-file-excel-o file-excel";
                        break;
                    case "doc":
                    case "docx":
                        str = "fa fa-file-word-o file-word";
                        break;
                    default:
                        str = "fa fa-file-file-o file-empty";
                        break;
                }

                return str;
            }

        }
 });
<div id="app">
  <div v-for="item in items">
    <div v-if="!_.isEmpty(item.files)">
        <ul >
            <li v-for="file in item.files">
                <i :class="fileIcon(file)">{{file.filename}}</i>
            </li>
        </ul>
   </div>
</div>
</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

You are unable to insert a variable within the channels.get() method in discord.js

Attempting to troubleshoot this issue has been quite frustrating. Despite my efforts, it seems that something is not working as expected. I can't help but wonder if I am simply overlooking a simple mistake due to fatigue. Here's the scenario: It ...

Internet Explorer attempts to store script while Ajax Form jQuery plugin processes form submissions

Whenever I attempt to submit a form using the jQuery Form plugin (http://jquery.malsup.com/form/) and set contentType: script, I encounter an issue where Internet Explorer displays a "Save as" pop-up prompting me to save the response script. Here is an ex ...

Having trouble with the Mysqli query not functioning properly in PHP code after being dispatched via Ajax

I am encountering a problem with a specific Myqsli query. $sqlselect = "SELECT visitatori_id FROM visitatori WHERE visitatori_nome='".$nome."' AND visitatori_cognome='".$cognome."' AND visitatori_orastart='".$time."' AND v ...

Error: The index "id" is not defined

Hey there, I have been working on fetching data from a JSON URL located at this link. However, I seem to be encountering an error that I can't quite comprehend. If anyone has any insights or solutions, I would greatly appreciate the help. Thank you in ...

Failed to validate user profile because of an InternalOAuthError error while using passport-facebook-token to verify the token

In my iOS application, I am utilizing the Facebook API for user login and receiving an access token in return. Now, I need to use this token to verify a user on my backend server. For this purpose, I have implemented the passport-facebook-token strategy w ...

Does the Angular templateCache get shared across different applications? And does it stay persistent?

Is it possible for two Angular applications that operate on the same domain to exchange data within the templateCache? Or does each main application module have its own unique cache? I am curious about the circumstances under which a new templateCache is g ...

Retrieve tabs according to the value selected in the dropdown menu

When a value is selected from a dropdown with options 1 to 5, I want to display a corresponding number of tabs. Below is the HTML code for the select box: <select id="Week" name="Week"> <option value="1">1</option> <option val ...

transferring data from a web page to a php script seamlessly without navigating away

I've already spent a significant amount of time searching on Stack Overflow and Google, but I haven't found a solution that works for me. My issue is that I have an HTML form and I need to send the data to PHP without redirecting or leaving the ...

Checking for the accuracy of the provided full name

There is a specific task at hand: The field labeled “First Name Last Name” must only contain 2 words, with each word being between 3 and 30 characters in length. Additionally, there should be only one space between the first and last name. The issue t ...

The use of Angular's ng-pattern leads to disruption in the binding process

Here is the form I am working with: <div class="panel-group"> <label for="url" tooltip="Enter the Engine as a Web Service (EWS) URL the Empower Editor will use for PDF preview.">EWS URL</label> <input id="url" size="50" ng-mod ...

What is the best way to incorporate custom styles in CKEditor with the help of the Custom drop

I recently implemented a plugin that provides me with the code needed to create a dropdown menu on my CKeditor toolbar. This dropdown menu contains various styles that can be applied by clicking on them. Here is the code snippet: CKEDITOR.plugins.add( &ap ...

What is the best way to ensure that all nested asynchronous jQuery AJAX requests are complete before proceeding?

Currently, I am utilizing jQuery to handle a series of asynchronous AJAX requests in a loop. I am aware that I can wait for all of them to be completed by utilizing the convenient '$.when.apply(array_of_requests).then()' method. However, I also ...

What exactly sets one string apart from another? (JavaScript)

Is it possible to use JavaScript to detect the specific part of strings that makes them different from each other? For example, consider the following three strings: String1 = "Java1String" String2 = "Java2String" String3 = "Java3String" If String1 is t ...

Struggling with eliminating the # from a URL in AngularJS

I am working on a single-page application built with AngularJS. The URL structure I currently have looks something like this: .../Angular/index.html. However, when I click on a link within the page, the URL transforms to .../Angular/index.html#/addStudent. ...

Struggling to override a css element in a responsive design

Here is a Link that I am having trouble with. Within my CSS, I have an element named tbox. It functions as an inline box with a width set at 100%. On the homepage, it adjusts its width perfectly based on its parent and is fully responsive. However, when na ...

Maximize Rotation - JavaScript Rotation

Currently tackling a Codewars challenge. The task involves finding the maximum possible result after performing a rotation on a given number. This rotation is unique in that 'n' number of digits will remain fixed after each rotation, with &apos ...

The form submits automatically upon loading the page with empty input fields

I recently created a form on my website located at . Initially, the form functioned correctly and the PHP script executed as expected. However, I am now encountering an issue where every time I load the page, a popup message appears indicating that the for ...

Encountering errors with vue-cli-service build on Heroku deployment

I am experiencing an issue with deploying my basic application on Heroku. The app, built using the default vue-cli setup along with a few components and views, compiles successfully when running 'vue-cli-service build' locally. However, when atte ...

Developing a project similar to the one designed for three.js

I'm excited about recreating something similar to the example in this video: http://www.youtube.com/watch?v=gYGzsM4snmg. Can anyone provide guidance on where to find the source code or offer a beginner-friendly explanation, considering I am new to thr ...

State in Vuex can be modified by invoking the store actions

Currently, I have implemented two functions in my store. One function retrieves data by making API calls, while the other function toggles changes on the "approved" cell. Everything seems to be functioning correctly, except for the fact that after toggling ...