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

What could be causing the unexpected behavior of angular.isNumber()?

I'm encountering an issue with AngularJS's angular.isNumber, as it doesn't seem to work with strings that represent numbers. Is there a mistake on my end? Would utilizing isNaN() be a better approach? angular.isNumber('95.55') == ...

Slider handle for Material UI in React component reaches the range value

In my application, I am using a range slider component from material-UI. The main page displays a data table with the fields: id, name, current price, new price. The current price for each item is fixed, but the new price will be determined based on the s ...

What are the drawbacks of calling async/await within a fresh Promise() constructor?

I have implemented the async.eachLimit function to manage the maximum number of operations concurrently. const { eachLimit } = require("async"); function myFunction() { return new Promise(async (resolve, reject) => { eachLimit((await getAsyncArray ...

Is it possible in Vue.js to create a reactive functionality for a button using a watcher for "v-if" condition?

I have a userlist page with various profiles, including my own. A button is supposed to appear only when viewing my own profile. The issue arises when switching from a different profile to my own (changing the router parameter) - the button should show up ...

Invoke `setState` function in contexts outside of React framework

Is the following approach guaranteed to work correctly within React v18 semantics? The "rules of hooks" only address calling the hook within the component, with no mention of whether it's acceptable to call the dispatcher returned from the ...

Implementing JavaScript to Activate Radio Button on Mouse Click

I am relatively new to JavaScript and I am working on setting up an automator to handle some repetitive tasks on a work website. Today, I have spent several hours trying to use JS to select the second radio button out of two. I thought the following code s ...

Enhancing Your WordPress Menu with Customized Spans

I have a WordPress menu structured like this: <div id="my_custom_class"> <ul class="my_custom_class"> <li class="page_item"><a href="#">page_item</a> <ul class='children'> <li class="page_item chil ...

Is it possible to alter the source of a component in Vue.js routes based on different environments using an 'if'

Within a vue project, there are certain environment variables that need to be taken into consideration. The goal is to dynamically call components based on these variables. How can an if statement be used in the router file to achieve this component swit ...

What causes the index link to break when react-router's setRouteLeaveHook is used?

Issue: Whenever I include router.setRouteLeaveHook() or router.listenBefore() in my component, it causes the logo homepage Link to path="/" to break Scenario: I am attempting to implement a confirmation prompt before leaving a section. Below is the code f ...

Building Your Own Array Object in JavaScript

Yes, it may seem crazy at first glance, but let me clarify things a bit. When using Jquery, for instance $('div'), it returns an Array Collection similar to this: [div#container, div#header, div#logo]. The interesting part is that primitive Arra ...

"What is the process for developing a Web-component with Vue and typescript that can be used in

Utilizing vue-custom-element, I have successfully created a Web component in Vue and integrated it into Angular. This setup operates seamlessly for Vue+js: import Vue from 'vue' import Calculator from './components/Calculator.vue' impo ...

There appears to be a JavaScript validation error occurring on the current page, however, you are able

For my datepicker, I want an error message to display if the user selects a date more than 5 years in the future, saying "You are ineligible for our program". The user should not be able to proceed to the next step unless this error message is ad ...

The functionality of the React Router DOM seems to be malfunctioning

I am facing an issue with running a program on my computer while it runs successfully on other PCs. When I try to run this program, I encounter the following error message. Any help in fixing this would be greatly appreciated... index.js import React, {C ...

Transfer a term to a different division - JavaScript Object Model

I am trying to achieve a specific task where I need to move one term under another in SharePoint. However, despite my efforts using JSOM and SharePoint 2013, I have not been able to find a direct method for moving terms. The code snippet I have used below ...

What is the best way to retrieve the value of an input field in React when incorporating Material UI components?

I am working with a few radio input components that have been imported from material Ui react. Each radio input is wrapped in a FormControlLabel component. <FormControlLabel onClick={checkAnswerHandler} value={answer} control={<Radio color=&quo ...

Steps to fix issues with Cross-Origin Read Blocking (CORB) preventing cross-origin responses and Cross Origin errors

var bodyFormData = new FormData(); bodyFormData.set("data", "C://Users//harshit.tDownloads\\weather.csv"); bodyFormData.set("type", "text-intent"); //axios.post("https://api.einstein.ai/v2/language/datasets/upload", axio ...

Troubleshooting: Issues with JQuery validation for cross-domain URLs

I'm fairly new to using JQuery and I have a specific requirement which involves validating a link from another domain. If the validation is successful, I need to redirect (open the page in a new window) to that link. Otherwise, I should display an ale ...

Navigating a secure Koa authentication flow using compose mechanism

I have this isAuthenticated function in expressjs that composes middleware into one. Now, I need to achieve the same functionality in Koa as I am migrating from Express. How can I replicate this in Koa? import compose from 'composable-middleware&apos ...

Issues with displaying HTML5 audio player in iOS Chrome and Safari browsers

My html5/jquery/php audio player is working well on desktop browsers, but when I tried testing it on iOS, all I could see was a grey track bar. I suspect that the controls are hidden behind the track bar because sometimes the associated file starts playing ...

Is there a way to obtain the component code prior to compiling in Vue2.x?

What is the purpose of this feature? <code-box title="基本" describe="button基本用法"> <i-button>Default</i-button> </code-box> I need to retrieve the default Slot String like <i-button>Default& ...