Vue issue rendering v-html inside of a table - vue.js

I am trying to inject vue tags dynamically using v-html. However, it does not render as expected. I have attached a link to a jsFiddle example, where I try to add a v-icon via v-html. Instead of the tag being correctly injected, it strips the tags away and only renders the content inbetween.
Example:
The following code works fine, but it is not dynamic. What If I want other html tag(s) beside v-icon?
<table>
<tr>
<td><v-icon>mdi-car-side</v-icon></td>
The following code does not work, but is dynamic. It just places the icon name on the screen, and strips away the tags.
<table>
<tr>
<td v-html="dynamicData"></td>
https://jsfiddle.net/cgbwe31t/1/
I have read the blurb here https://v2.vuejs.org/v2/guide/syntax.html#Raw-HTML about 'Note that you cannot use v-html to compose template partials, because Vue is not a string-based templating engine', but I'm not sure that applies in this case.

In case anyone was wondering, the best solution is to use v-slot to insert any html you want.

Related

How to put a component inside innerHTML in VueJS

I need to put some HTML code inside innerHTML but I have also some components that need to use like 'vue-feather-icons', I have tested many ways but I didn't find the solution yet.
my tries are
<div class="blog blog-block" v-html='`<div>${<ChevronLeftIcon></ChevronLeftIcon>}</div>`'>
<div class="blog blog-block" v-html='`<div><ChevronLeftIcon></ChevronLeftIcon></div>`'>
There is a correct way to put a componenet inside innerHtml

Parse string with components inside to template in vue.js

Is it possible to parse string with components inside to template in vue.js? Example of string:
"Some text, some <b>bold text</b>, and inserted image from this
component <vue-simple-image :src='images/my_image_name.png' />, another text and html tags."
It looks like I need store such strings to database to use them later for recreating user input from vue-wysiwyg editor.
In the strict sense you asked the question, I do not think this is possible. There is a v-html directive, that can render html for you but not components. This is also considered an anti-pattern, as the vue guide states:
Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS attacks. Only use v-html on trusted content and never on user-provided content.
You could look into dynamic components in order to render vue components based on user input.
You could parse the wysiwyg user input, split the string on recognized vue-component tags (so you have an array of pieces of elements with sequences of regular html and elements that are single vue-components), and then use a template with v-for looping to render this. (non-working pseudocode) example:
<div id="renderedWysiwygInput">
<div v-for="elem in splitInput">
<component v-if="stringIsVueComponent(element)" v-bind:is="element"></component>
<div v-else v-html="element"></div>
</div>
</div>
You'll have to work this example out a bit more though to account for the possibility of input inside the vue components themselves, for example if you are filling slots. I would try to limit what kind of input you are going to support to keep it manageable.
No, this is not possible, because Vue component is not just an html piece, it is a js class. So you need to register it properly and so on...

How to replace DOM elements with a Vue component?

I inject raw html into my page. I would like to extract all the <a> elements in this and replace them with my <custom-link-component>. Is there a way of doing this with Vue?
I get raw html from the data service and inject it into a vue component using v-html.
So far I have a mixin that finds all <a> elements but can't work out how to replace them:
const links = document.querySelectorAll('a');
Many thanks.
I think it's not possible to achieve what you want in this way. If you want to use vue component instead of links, you have to place them in your markup as components like vue router-link as an example:
<!-- literal string -->
<router-link to="home">Home</router-link>
<!-- renders to -->
Home
It was discussed here, look like same question.

How to disable replacing the app root div with the component HTML while using templates

So basically, when using components - the app root passed to the Vue instance gets replaced by whatever HTML is in the component. Is there a way to disable this and just nest the stuff Vue renders inside the app root instead?
for example - if index.html has a wrapper of
<div id="myVueApp"></div>
and I set el: "#myVueApp" on the Vue instance, the whole node will get removed and replaced by whatever I have in my template resulting in
<div id="myComponent">...</div>
Is there a way to make it into
<div id="myVueApp">
<div id="myComponent">...</div>
</div>
Should work. From what I understand, you want to have multiple parts of your Vue app to be splitted up in the rendered HTML output as well, more specifically into multiple divs.
I think this should work if you use multiple Vue instances.
Set up a structure in your HTML file and give them appropriate id's.
Then, create the Vue instances you want and assign each of them to their specific div using el.
However, I can't tell you if this is a good idea and follows the best practice..
Hope this helps!

Escape vue components in html

I'm struggling to make a table with component / HTML example pairs.
Here's the example of what I did (it doesn't work):
<td>
<vm-three-state-checkbox-filter
name="three-checkbox"
></vm-three-state-checkbox-filter>
</td>
<td v-pre>
<pre>
<vm-three-state-checkbox-filter
name="three-checkbox"
></vm-three-state-checkbox-filter>
</pre>
</td>
And here is the result:
One the left you can see the rendered component, on the right i expect to see raw html instead of nothingness I'm presented with.
I can specify the escaped HTML as string in data and that would work (vue escapes strings by default), but I'd prefer to do it in template.
Thanks for help in advance.
The v-pre directive keeps Vue from compiling anything inside that element.
So your <vm-three-state-checkbox-filter> element stays in the browser as it is in the template, and as that is not a valid HTML element, the browser displays: nothing.
v-pre does not HTML-escape anything for you. It only keeps Vue from compiling the Vue-template-code stuff - components, directives, mustache {{}} tags.
You could probably write a small custom directive (with the terminal: true option enabled) that would convert the HTML elements inside into an escaped string, but that's not something I can throw together on the spot.
HTML code not escaping with tag.