Vue: v-once whitelist and additional directives

Created on 25 Jul 2017  ·  9Comments  ·  Source: vuejs/vue

What problem does this feature solve?

If a single child of a v-once parent requires reactivity then we can not use v-once on the parent element but must apply it to all the siblings of the reactive element/component instead. It would be nicer if we could whitelist the reactive children of an element or component that has v-once with some additional proposed directives.

Whitelists are usually a better strategy, especially for security, than blacklists.

What does the proposed API look like?

Ideally we would be able to do this:

<div v-once>
    <h1>static text</h1>
    <h1 v-exclude>{{non-static text}}</h1>
    <h1>static text</h1>
    <h1>static text</h1>
</div>

instead of the following:

<div>
    <h1 v-once>static text</h1>
    <h1>{{non-static text}}</h1>
    <h1 v-once>static text</h1>
    <h1 v-once>static text</h1>
</div>

Some additional directives proposed:

  • v-always: takes precedent over v-never and always excludes an element/component and its children
  • v-never: takes precedent over v-exclude and never excludes an element/component and its children
  • v-exclude: exclude a specific element/component and its children from v-once
feature request

Most helpful comment

v-once should really only be used on chunks of template that are significantly large and costly to render, otherwise the benefit would be negligible. Most applications perform perfectly fine without the need for v-once at all. The cost of introducing these additional directives/concepts, both technical and API surface increase, are not really worth it.

All 9 comments

I'll rather have v-once-exclude and v-once.force (takes precedence)
I think adding something like v-once-exclude.force would be too much

We are kind of in an API freeze except for very useful additions/ new features. Syntax sugar is generally not in that category I think.

I agree, but I wasn't seeing this as syntax sugar. It really is something new that cannot be achieved at the moment.
I personally think that nit picking nodes to render with Vue is out of Vue scope and too much of an edge case (can we really have performance issues that could be solved with this FR, I doub it) to actually add the FR.

Well, since vue-loader already caches static child trees in staticRenderFns, purely static parts of the template are already only rendered "once"...

More so I was actually thinking of cases where the author of a component is unsure of the context in which their component will appear.

@LinusBorg Are you sure about that? I tried quickly using (Vue.compile and) vue build with

  <div>
    <p class="hey">{{ text }}</p>
    <span class="ha">Hello</span>
  </div>

And it won't add any staticRenderFns

@RobertBColton What's the point of using v-once in that situation

@posva The question I am referring to is actually "will the user of my component be using v-once? can I prevent them from doing so?"

@posva See https://github.com/vuejs/vue/blob/dev/src/compiler/optimizer.js#L75, template below will generate static render function.

<div>
    <p class="hey">{{ text }}</p>
    <p><span class="ha">Hello</span></p>
</div>

IMO the costs of implementing this feature is heavily outweigh its benefits.

v-once should really only be used on chunks of template that are significantly large and costly to render, otherwise the benefit would be negligible. Most applications perform perfectly fine without the need for v-once at all. The cost of introducing these additional directives/concepts, both technical and API surface increase, are not really worth it.

Was this page helpful?
0 / 5 - 0 ratings