Vue: Configuration for empty VNode not to render to <!---->

Created on 7 Mar 2017  路  8Comments  路  Source: vuejs/vue

I have been working on an infinite scroll list plugin for Vue.js 2.1+.
It basically use 'v-if' to implement DOM recycling, meaning that when the list gets long enough,
there will still only be limited DOMs exists so that scrolling performance remains good.

The idea comes from this article Complexities of an Infinite Scroller,
I found it will be useful if the idea can be implemented with Vue, so there comes out this plugin.

So far it works pretty well, with scoped slots, it's highly customizable.
But there is this tiny problem, empty VNode will be rendered to this <!----> html comment string.
This is definitely not a bug, and I found the empty comment string is used for Vue unit test.

However, when developing and inspecting elements, the developer tools panel is full of <!---->s.
image
Check out the repo and example page.

It seems have no influence on performance, only a little annoying to developers.
So is there any way to get rid of these empty comments?

Most helpful comment

v-if is usually used for elements in a relatively stable node structure, rendering it to empty comment tags makes vnode lists diffing more efficient as the lists are more "stable", and it avoids some edge cases when elements are not keyed. In your case it doesn't seem to cause any real issue other than small inspection annoyance, so unfortunately I don't think we would change this behavior.

For virtual scrolling lists, it maybe a better idea to use a computed property to return a subset of the items that needs to be rendered, e.g. v-for="item in displayedItems" instead of using a v-if on each item.

BTW, nice project, the demo is very smooth!

All 8 comments

v-if is usually used for elements in a relatively stable node structure, rendering it to empty comment tags makes vnode lists diffing more efficient as the lists are more "stable", and it avoids some edge cases when elements are not keyed. In your case it doesn't seem to cause any real issue other than small inspection annoyance, so unfortunately I don't think we would change this behavior.

For virtual scrolling lists, it maybe a better idea to use a computed property to return a subset of the items that needs to be rendered, e.g. v-for="item in displayedItems" instead of using a v-if on each item.

BTW, nice project, the demo is very smooth!

Thanks Evan! As you suggested, I removed v-if and added a computed subset property, and now it works smooth and tidy!

Hi,

I ended up on this issue because I also have some Vue comments inside my div and the CSS selector div:empty { padding:0; } does not work with comments, only if they are inline.

https://css-tricks.com/almanac/selectors/e/empty/#article-header-id-1

I read Evan's comment and I'll find a workaround, but just to be sure, is there any change since the issue reported here regarding this subject?

Thank you,
Adrian

PS: I love Vue (sounds funny)

I have same issue. :empty css selector does not work.

This has caused issues for me as well. My use case is that I'm migrating a legacy app to Vue, and trying to do it incrementally because it's a fairly non-trivial project. I'm trying to keep the html markup of my rendered Vue component as close as humanly possible to that from before the migration, because the app stores state in the DOM which the legacy components will access with jQuery. The presence of the comments means hard assumptions about that html are now being violated.

Whereas code like

var status = $j('[data-id=' + someVar + ']').find('.classSelector').html();
$j.trim(status) === "Some particular state"

used to return true for some given state of the app, it now returns false, because the html content has now changed from 'Some particular state' to Some particular state <!---->, because I've switched from server-rendered html to a Vue component including a v-if.

I'm not posting this in the expectation you'll rewrite Vue based on some badly factored legacy jQuery, but just as some further feedback from a user who has struggled with an empty comment actually affecting the behaviour of the app. (Also, any suggestions for a workaround from the Vue side would be gratefully received!)

I have faced the same issue while trying to implement something by :empty selector like this Building Skeleton Component....

If anyone also has the issue, here is a tricky solution:

<template lang="pug">
    .component-name
        template(v-if="expression")
            .content-part
        template(v-else)
</template>

With a empty template and v-else, the empty comment node disapperead and :component-name:empty works.
Anyway, a configuration to avoid rending to <!----> is preferred.

Disappointing that no one (looking at you, @yyx990803) addresses the fact that this makes using the :empty CSS pseudo selector unusable. What's the workaround?

Disappointing that no one (looking at you, @yyx990803) addresses the fact that this makes using the :empty CSS pseudo selector unusable. What's the workaround?

You could just set a class to the parent if none of the elements are shown and check for the class in CSS.
Also please don't necro this issue, it has been closed for over three years.

Was this page helpful?
0 / 5 - 0 ratings