What is the best method to display a component using a string in Vue 3?

I've been attempting to render a component from a string without success. Here are my codes:

<template>
<div v-html="beautifyNotification(notification)"></div>
</template>

<script>
import { Link } from '@inertiajs/inertia-vue3'
import {compile,h} from "vue"

export default {
    components: {
    },
    props: {
        notifications: Object
    },
    methods: {
        beautifyNotification (ntfction) {
            return h(compile(`<Link :href="`+ntfction.from.username+`"
                    class="h6 notification-friend">`+ntfction.from.name+`
            </Link>, commented on your new
            <Link href="#" class="notification-link">profile status</Link>.`))
        },
    }
}
</script>

I attempted to render the component using h and compile but it resulted in object object

Answer №1

If you've stumbled upon this in search of a solution, fear not! I've traversed the treacherous path of incorrect answers so you don't have to (it's surprising how many supposed Vue 3 solutions out there just don't cut it). Even sought help from the 'advanced' realm of Vue Discord, only to be met with strange and inaccurate responses.

Even the answer provided by Maembe didn't do the trick for me (lacked access to other components/scope).

Here is the flawless solution that worked wonders for me:

Behold my CompiledContent component, capable of handling a blend of HTML and Vue components within a single string fetched from the backend.

Note that it doesn't rely on the compile function at all.

<script>
import { h } from 'vue';
import AppAlert from '@/components/AppAlert.vue';

export default {
  props: {
    content: {
      type: String,
      default: '',
    },
  },
  render() {
    const r = {
      components: {
        AppAlert,
      },
      template: `<div class="content">${this.content || ''}</div>`,
      methods: {
        hello() {
          // method "hello" is also available here
        },
      },
    };
    return h(r);
  },
};
</script>

If your content includes numerous components, consider converting them all into asynchronous components:

components: {
  AppAlert: defineAsyncComponent(() => import('@/components/AppAlert.vue')), 
  ...

Answer №2

Despite the delayed response, I am here to address this question utilizing the static compilation method.

Advantages:

  • Fast and less CPU intensive: Utilizes native compilation rather than including the heavy Vue compiler in your package
  • Saves memory: This method only uses Vue's prototype functions, avoiding memory consumption from including the compiler

Drawbacks:

  • Does not support SFC syntax: As a native compiler, it does not accept regular {{ value }}, though you can add one. It supports event syntax @click=... and component prop support with reluctance

import { Fragment, h, Component, defineComponent } from "Vue"

// Functions for building elements and compiling children
...

export function compiler(html: string, components: Record<string, Component>) {
  // Compiles HTML using given components
  ...
}

A simplified version for those unfamiliar with Vue's low-level APIs who would typically use openBlock

Demo links:

https://i.stack.imgur.com/oy0Oo.png

View Demo

Answer №3

It seems that the h function is being misused in this instance. The h() should be returning a virtual node intended for use within a render() function rather than a template. Therefore, there is no need for a <template> or <v-html> at all in this scenario:

//no template element
<script>
import { Link } from '@inertiajs/inertia-vue3'
import {compile,h} from "vue"

export default {
    props: {
        notifications: Object
    },
    render() {
        return h(
           // abbreviated template string used for concise representation
           compile('<Link href="#" class="notification-link">profile status</Link>')
        ) 
    }
}
</script>

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

The ChromeDriver capabilities that have been configured are not maintained once the WebDriver is constructed in Node Selenium

I am currently experimenting with adding the default download path using Chrome capabilities in my code snippet below: const test = async () => { let builder = await new Builder().forBrowser("chrome"); let chromeCapabilities = builder.getC ...

Mastering the art of iterating through a JSON response

Looking to populate a combobox with data from the database. Upon accessing mystream.php?theLocation=NewYork, I receive the following JSON response: RESULT {"result": [{"theID":"36"},{"theStream":"0817-05131"},{"theLabel":"hgjbn"},{"theLocation":"NewYork ...

Exploring Vue 3: Unpacking examples within the setup function and implementing them within the Setup tag

Although I am new to Vue, I decided to dive straight into TS and the Setup tag because they are considered the newest and most efficient way to write Vue.js components. Currently, I am exploring this framework, with a specific interest in the following ex ...

Create a drag-and-drop interface and link elements together using a custom JavaScript library

Seeking a solution or Javascript library to create a scientific modeling application, similar to flowchart software such as Visio. The ability to add elements and connect them by clicking and dragging is essential. https://i.stack.imgur.com/vSZpB.png The ...

What are the steps to troubleshooting using VS Code and Chrome browser with Webpack?

Can anyone provide guidance on how to debug webpack in VS Code with the Chrome browser? As a beginner in programming, I'm struggling because webpack minifies everything into one line which makes traditional debugging methods ineffective. I haven' ...

Ways to assign an identification attribute to HTML elements within innerHTML

Utilizing Ajax in conjunction with php $("#test1").click( .... function(data){ document.getElementById("test2").innerHTML=data; } ) php will return the data echo "<input type='text' id='test'>"; Seeking adv ...

What is the process for setting up a server with Node.js?

After diving into my nodejs studies, I hit a roadblock at the point where I was supposed to create a server. Here's the code snippet for this particular script: var http = require('http'); // Import Node.js core module var server = http.cre ...

vue implementing autoscroll for long lists

I am looking to implement an autoscrolling log feature on my webpage that is dynamically fetched from a REST endpoint. To handle the potentially large size of this log, I decided to use vue-virtual-scroll-list. Additionally, I wanted the log to automatical ...

Update the form action URL when a specific option is selected from the dropdown menu upon clicking the submit

I would like my form to redirect to a specific page on my website based on the selection made in the <select> tag. For instance, if '2checkout' is selected, it should go to gateways/2checkout/2checkout.php. Similarly, if 'Payza' i ...

Exploring the power of Angular by implementing nested ng-repeat functionalities:

I am currently working on an ng-repeat feature to add items from the array (album array). Everything seems to be functioning correctly. However, I also have a colors array that should assign different background-colors to the card elements of the album arr ...

children blocking clicks on their parents' divs

I previously asked a question about a parent div not responding to click events because its children were blocking it. Unfortunately, I couldn't recreate the issue without sharing a lot of code, which I didn't want to do. However, since I am stil ...

Reactive Form value is not displaying in view because of FormControlName issue

I have successfully retrieved data from the database and need to pre-fill an update form with preset values. The issue I am facing is that when I add FormControlName to the input field, it removes the preset values. I have tried using setValue and patchV ...

Creating a div resizing function using only JavaScript is a fun and useful project to tackle

Seeking help to create a div resizer using only pure JavaScript as jQuery is restricted. The current functionality works, but breaks when the position of the slider-div is not set to absolute. Any solutions to fix this issue would be greatly appreciated. ...

When the button is clicked, send data using 'POST' method to the php file and fetch

<script> $(document).ready(function(){ $("#vE_rebtn").click(function{ var reverifyEmail = '<?php echo $_SESSION["verifyEmIPv"]; ?>'; $('#rE_rebtn').hide(); $('#re_ ...

What is the best way to share image data between pages in Next.js?

I'm currently developing a project that mimics Instagram (simply because I want to explore Next.js further) and I'm looking for a way to handle image uploads. My goal is to allow users to upload their images and then redirect them to the "create ...

Guide on developing a Vue modal for transferring user input to a separate component

I have been working on creating a modal component that allows users to input data and then displays it in another component. For example, the user is prompted to enter their first and last name in a modal component (Modal.vue). Once the user saves this inf ...

Error alert: The function name used in the import statement is not defined

I've taken the initiative to organize my JavaScript functions into separate files based on their respective web pages (index, login, register, etc.), and then importing them all into a main JS file. This helps with code maintenance and readability, pr ...

Accessing data from an API in an AngularJS dropdown menu

After retrieving JSON data from an API, I store it in $scope.industry. $scope.industry = []; $http.get('/industrygroup?languageid=1') .then(function (result) { $scope.industry = result.data; }); The JSON data st ...

Oops! You're trying to perform actions that must be plain objects. If you need to handle async actions

I have been struggling to implement Redux and pass an object into the store. Although I am able to fetch the correct object when I call the action, the store remains unchanged when I use store.dispatch(). It still only reflects the initial state. I've ...

The Vue EventBus does not support passing object attributes

Looking for assistance with integrating two Vue single page components. The 'Searchbar' component features a dialog box where users input data. This data is required in the 'ResultList' component for further processing. To achieve this ...