1. Overview
In this article, we will learn to fix the warning (deprecation COMPILER_NATIVE_TEMPLATE) <template> with no special directives will render as a native template element instead of its inner content in Vue 3.
2. Native template element
First, let’s recall the native template element and its behaviour.
The native <template>
HTML element is a mechanism for holding HTML that is not to be rendered immediately on page load but may be instantiated subsequently during runtime using JavaScript.
Think of a template as a content fragment that is being stored for subsequent use in the document. While the parser processes the contents of the <template>
element while loading the page, it does so only to ensure that those contents are valid; however, does not render the element’s contents. You must render at runtime using JavaScript or so.
3. Vue js 3 breaking changes
In Vue js 3, the <template>
tags with no special directives (v-if/else-if/else
, v-for
, or v-slot
) are now treated as plain elements and will result in a native <template>
element instead of rendering its inner content.
Let’s go through some scenarios where you could encounter this warning:
3.1. Template with no special slot and slot-scope directives
If you are migrating from Vue js 2 to 3, you must use the v-slot directive rather than using the slot and slot-scope attributes with the slot.
Vue js introduced a new unified syntax (the v-slot
directive) for named slots. It replaces the slot
and slot-scope
attributes, which are deprecated in v2.6+ and removed in Vue 3.
You can go through this link to understand the named slots. Named slots are useful when you want to display multiple fragments in a single child component.
Before v2.6, to pass content to named slots from the parent, you should have used the slot
attribute on <template>
to identify the place within the child component to load the content:
<base-layout> <template slot="header"> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template slot="footer"> <p>Here's some contact info</p> </template> </base-layout>
Now from Vue 3 onwards, you must use the v-slot
directive with <template>
as below:
<BaseLayout> <template v-slot:header> <!-- content for the header slot --> </template> </BaseLayout>
3.2. Template with no special directives
Before Vue 3, Vue js will render a template with no special directives in the default slot, meaning a slot with no name.
For example, the second template doesn’t have any special directives.
<template> <BaseLayout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <template> <p>A paragraph f or the main content.</p> <p>And another one.</p> </template> <template v-slot:footer> <p>Here's some contact info</p> </template> </BaseLayout> </template>
Vue js renders the second template in the default slot of the child component. Here, the template is rendered with the main
element.
<template> <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template>
With Vue 3 and above, you cannot use template elements in this way. You must specify any special directive, otherwise, it behaves as the native HTML element. So, Vue js will not render the contents of the <template> with no special directive on page load.
3. Conclusion
To sum up, we have learned to fix the warning (deprecation COMPILER_NATIVE_TEMPLATE) <template> with no special directives will render as a native template element instead of its inner content in Vue 3.