Creating Virtual Nodes from a string with HTML tags in Vue 2.5: A Step-by-Step Guide

Having some trouble creating a functional component that displays the Feather Icons package - I'm stuck on the final step. Here's what I have so far:

This is my FeatherIcon.vue component.

<script>
const feather = require("feather-icons");

export default {
  components: {},
  props: {
    type: {
      required: true,
      type: String
    }
  },
  mounted() {},
  render(createElement) {
    return createElement(
      "svg",
      {attrs: feather.icons[this.type].attrs },
      feather.icons[this.type].contents
    );
  }
};
</script>

In Vue documentation, it says that the 3rd argument should be either:

// {String | Array}
// Children VNodes, built using `createElement()`,
// or using strings to get 'text VNodes'. Optional.

However, the value of my 3rd argument feather.icon[this.type].contents is a string containing the "innerHTML" inside the svg tag:

"<line x1="6" y1="3" x2="6" y2="15"></line><circle cx="18" cy="6" r="3"></circle><circle cx="6" cy="18" r="3"></circle><path d="M18 9a9 9 0 0 1-9 9"></path>"

So my question is, how can I convert feather.icon[this.type].contents into a set of VNodes?

I've attempted using DOMParser and parseFromString but haven't had any success. Any suggestions?

Answer №1

You have the option to utilize the domProps property within the data object.

This feature enables you to bind standard HTML attributes and DOM properties like innerHTML (replacing the v-html directive).

Below is an illustration.

console.clear()

const content = `
  <line x1="6" y1="3" x2="6" y2="15"></line>
  <circle cx="18" cy="6" r="3"></circle>
  <circle cx="6" cy="18" r="3"></circle>
  <path d="M18 9a9 9 0 0 1-9 9"></path>
`

new Vue({
  el: "#app",
  render(h){
    return h("svg", {domProps:{innerHTML: content}})
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app"></div>

In your scenario, simply assign innerHTML to the feather's content.

Moreover, if you lack a template, typically, a standalone javascript file suffices. A single file component isn't necessary. Hence, your component could be as follows:

FeatherIcon.js

const feather = require("feather-icons");

export default {
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(createElement) {
    return createElement(
      "svg",
      {
        attrs: feather.icons[this.type].attrs,
        domProps: {
          innerHTML: feather.icons[this.type].content
        }
      });
  }
};

Lastly, if you aim to convert this into a functional component, you can implement something like this:

const FeatherIcon = {
  functional: true,
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(h, context){
    const {contents, attrs} = feather.icons[context.props.type]
    return h("svg", {attrs, domProps: {innerHTML: contents}})
  }
};

Here is a demonstration of it in action.

console.clear()

const FeatherIcon = {
  functional: true,
  props: {
    type: {
      required: true,
      type: String
    }
  },
  render(h, context){
    const {contents, attrs} = feather.icons[context.props.type]
    return h("svg", {attrs, domProps: {innerHTML: contents}})
  }
};

new Vue({
  el: "#app",
  components: {
    FeatherIcon
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<div id="app">
  <feather-icon type="eye"></feather-icon>
  <feather-icon type="activity"></feather-icon>
  <feather-icon type="award"></feather-icon>
</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

Having trouble retrieving property from an object while using Vue-MultiSelect during the select event

I am utilizing the Vue-Multiselect plugin to create an input dropdown box and extract the customer's last name from a form submission. However, I am encountering an issue where only an object is returned as the value of the issue.customer_last_name pr ...

results vary when using both a while loop and callback

I'm having an issue with my while loop when filtering data from mongodb. Even though I should be getting three entries logged to the console, only one entry is making it to the callback function. Can anyone explain why this is happening? while(i--) { ...

Is there a way to prevent Express.js from triggering a file download in the browser?

I am attempting to preview a Word document file in the browser using an iframe: <iframe style="float:right;" src="/ViewerJS/#../demo/ohm2013.odp" width='400' height='300' allowfullscreen webkitallowfullscreen></iframe> (Fo ...

Issue with fetching data using Tanstack query in Vue 3 with parameters is not resolved

Hey there, I'm seeking assistance with Vue3 Tanstack Query usage. I've already gone through the documentation and attempted to implement data refetching when parameters change, but for some reason, the API call isn't being triggered. Any sug ...

I am experiencing difficulty typing continuously into the input box in reactJS

In one of my components, I have the capability to add and delete input fields multiple times. <> <form onSubmit={optimizeHandler}> <div className="filter-container"> {conditions.map((condition, index) => ...

React not displaying wrapped div

I am facing an issue with my render() function where the outer div is not rendering, but the inner ReactComponent is displaying. Here is a snippet of my code: return( <div style={{background: "black"}}> <[ReactComponent]> ...

Learn the secrets of displaying a pop-up alert message seamlessly without interrupting the page's rendering process. Additionally, discover how to effortlessly refresh a chart every

I need to display a pop-up if the value is less than 3. I have tried using the alert function, but it causes the page to not render. How can I show the pop-up without blocking the page and refresh the chart every 30 seconds? <script> ...

Express 4: The requested route was not found by the router

Encountering a peculiar issue - the initial route functions properly, but when trying the parameterized route, a 404 error is returned. const express = require('express'); const router = express.Router(); router.route('/') .get(fu ...

Using the fetch method to consume a RapidAPI JSON response

Currently, I am in the process of learning React Native and have initiated a project for that purpose. In this project, I have integrated RapidAPI (link: ) to fetch necessary data. Upon hitting the API, I receive a 200OK status, but unfortunately, I am fa ...

What could be causing issues with my Ajax and JavaScript functionality?

While developing a website to search through my python database, I encountered an issue. The non-JavaScript version was functioning flawlessly. However, when attempting to implement AJAX so that the page would not have to be refreshed each time, I faced ...

The default theme has not been specified in Tailwind CSS

During my recent project, I utilized React, Next.js in combination with Tailwind CSS. In this project, I delved into styling customization by implementing react-slick for a specialized slider. To achieve the desired aesthetic, I made modifications to the r ...

How can I pass a dynamic scope variable to a JavaScript function in AngularJS that is being updated within an ng-repeat loop?

In my HTML, I have an ng-repeat loop where a variable is displayed in table rows. I want the user to be able to click on a value and pass it to a JavaScript function for further action. The code snippet below showcases my earlier version which successful ...

How to implement jquery select functionality on clickable table rows?

I've come across a challenge while trying to implement clickable table rows with the jquery selectable function. Everything works perfectly fine with li elements, but I seem to hit a roadblock when using tables - the click event just stops working. Wh ...

The progress bar for uploading a file is causing issues with the redirect function in the

I am currently facing an issue with my file submission form and progress bar in JavaScript. The progress bar is interfering with the controller, preventing it from redirecting back home with the link. I have tried removing window.location.href="/"; but thi ...

Numpad functionality in JQuery malfunctioning post-ajax request

Using the jQuery numpad plugin has been flawless until after an AJAX call. I have tried various functions like on('click') and others, but unfortunately, none of them worked as expected. Apologies for my poor English! You can find the extension l ...

Commitment within a forEach iteration

While working with a foreach loop, I am facing some challenges. Here is the scenario: I have multiple elements stored in an object array. For each object, I need to execute two queries. After completing the queries for one object, I move on to the next and ...

Efficiently encode and decode JSON data between PHP and JavaScript

I am attempting to convert my array results into JSON format and then transmit them to an AJAX success event using JavaScript. PHP $results = array( "time1" => 1, "time2" => 2, ); echo json_encode($results); JAVASCRIPT ...

Eliminate repeated elements within a JSON dataset to create a consolidated array

Looking to extract unique data from the JSON object below in order to create a result json with a list of questions and their corresponding choices. Any assistance would be greatly appreciated. Thanks in advance..!! var data = [ { "category": "s ...

Encounter an error parsing the package.json file. Confirmed that it is valid JSON

As I embark on creating my very first yeoman generator, I have encountered an issue when running yo to initiate the project. The error message I am receiving is as follows: npm ERR! install Couldn't read dependencies npm ERR! Darwin 14.0.0 npm ERR! a ...

Select component experiencing issue with Material Ui label breaking

I've been working on implementing a select component, which is new to me. However, I'm encountering an issue with my MUI-select component. The label of the select element is no longer syncing properly with the select component itself as shown in ...