Subscribe on changes!

v-if on template stops custom directive hooks from being called

avatar
Feb 19th 2022

Version

3.2.31

Reproduction link

jsfiddle.net

Steps to reproduce

Define an element with <template v-if="true" v-custom /> where v-custom simply logs directive hooks. Observe that with the v-if present, no hooks are called. Removing the v-if causes the hooks to be called again.

What is expected?

The directive hooks should run as normal regardless of the presence of the v-if.

What is actually happening?

The hooks are not called.


The fiddle I've linked includes a number of other combinations looking for potential workarounds. None of them work as I expect when using the template tag. Based on my understanding:

  1. example 1 turns on and off as expected, however the directive hooks do not run
  2. example 2 runs the directive hooks, however the content is not rendered
  3. example 3 runs the directive hooks, however the content is not rendered
  4. example 4 does not render the content
  5. example 5 works totally as expected (with a p tag)

Examples 2 through 4 appear to render as <template>#document-fragment.... Example 1 however renders the inner content and drops the wrapping template tag, which is what I'd expect of examples 2 through 4 as well.

avatar
Feb 19th 2022

<template> elements with v-ifon them are not rendered as actual elements, they serve as virtual wrappers to use a one v-if on a group of elements.

Since they are not rendered as elements, you can't use directives on them.

avatar
Feb 19th 2022

Ok, so a <template> with a v-if is handled specially by Vue, and there is no way get a genuine <template> tag to conditionally render.

Thank you. This explains the results of my tests, however it does break my expectations of the framework.

avatar
Feb 19th 2022

here is no way get a genuine <template> tag to conditionally render.

That's incorrect. You can of course nest two template elements to achieve what you wanted to do with one.

<template v-if="condition"> <!-- this one will disappear as it only carries the conditional -->
  <template v-custom> <!-- this one will be rendered -->
    whatever
  </template>
</template>