'VueJS 3 create/pass hyperscript to template at runtime?

I wanted to try something for performance/convenience purposes, I understand the gains will be minimal but understanding how/if/why this works would also just be helpful to learn.

I have a some custom data types (defined as classes) that are used to identify certain properties throughout my application. I want to use a static function on the type to define a display function. (stripped down) Example:

class Email extends String{
    static display = (value) => {
        return `<a href='mailto${value}'>${value}</a>`;
    }
}

Call it like you do:

Email.display("[email protected]");

And that works in the template, so long as it’s in a v-html attribute. This is perfectly acceptable.

It’s probably important to specify I’m working with Vue-CLI and single-file components, so all that sweet hyperscript gets created at compile time.

But it got me thinking, is there a way I can pass a freshly-created hyperscript to the template at render? Preferably in a way that works in the {{mustache}} if at all possible.

I tried doing it with h but that just displays the ol’ [object Object].

class Email extends String{
    static display = (value) => {
        return h('a', {innerHtml: value});
    }
}

Update: also tried

I thought maybe going around the Vue render functions could get the job done, but they don't seem to like document fragments either.

static display = (value) => {
    var fragment = document.createDocumentFragment();
    var a = document.createElement('a');
    a.textContent = value;
    fragment.appendChild(a);
    return fragment;
}

Question Is there a way create hyperscript at runtime and utilize it in a vue template? Bonus points if it works in {{mustache}} and v-html.



Solution 1:[1]

Generally component templates and render functions that use JSX or h (hyperscript) are mutually exclusive.

It's really possible to do this, in this case display is actually functional component, and it needs to be output as any other dynamic component:

setup() {
    const display = (props) => {
      return h(...);
    };

    return { display };
}

and

<component :is="display" :value="..."/>

The return of display is a hierarchy of vnode objects, they can't be used as is in v-html without being previously rendered to HTML.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Estus Flask