vue
vue copied to clipboard
Slots with only comments use fallback instead
Version
2.5.16
Reproduction link
https://jsfiddle.net/sg0bkLhv/7/
Steps to reproduce
- Register a component with a slot
- Use the component in a Vue instance with comments=true, filling the slot with only HTML comment(s)
What is expected?
The HTML comment is rendered into the slot.
This could be a breaking "fix" for someone who is running with comments=true and still relying on this behavior. If the current behavior is kept, I think it should at least be documented.
What is actually happening?
The HTML comment is discarded and the slot uses its fallback content instead.
If any other content is provided together with the HTML comment, all content is kept.
I am developing for a CMS which uses HTML comments to provide its editing capabilities. It has the concept of "areas", which are similar to Vue's slots, so it would be handy to render areas into slots. An empty area (e.g. in a newly created page) consists solely of an HTML comment. Since the comment is stripped by Vue, the editing tools are not available.
Try to use a variable instead of a string inside the <my-component></my-component>
.
See this example: https://jsfiddle.net/sg0bkLhv/90/
Thanks, @webther! It does seem to cover some cases: https://jsfiddle.net/wz5y3svp/.
However, it has some problems as well:
- v-html does not accept direct string input, but instead goes looking for data or props in the parent component. I think parents should not have to be aware of the contents of their children.
- v-html will also not work when the content includes other Vue components, since it is inserted as raw HTML instead of being compiled. Using a slot instead work since the comment is no longer on its own in this case, but it is again not nice to have to inspect content from outside the component.
If you want to use the inline html string, I think you should encode the html tags like this:
<my-component> <!-- kept --> </my-component>
See the example: https://jsfiddle.net/wz5y3svp/3/
It should still be treated as an HTML comment, not rendered as text. The second example renders correctly but relies on a data property in the parent instead of allowing text to be rendered directly into the template (server side, pre-Vue).
Our workaround for now is to append <div style="display: none;">
when we detect an empty area. This is not amazing as it requires code in every affected template (and may affect styling), but since it at least works, I am more interested in seeing whether this behavior is a bug or intended.
This is a problem for me. Wasted some time trying to figure out why my application stopped working. It was due comment as a slot...