Vue.compile encounters issues with nested HTML elements exceeding two levels deep

When using Vue.compile to handle async HTML, it appears that there is a limit of two elements deep before encountering an error. Rendering anything deeper than that results in

Error in render: "TypeError: Cannot read property '0' of undefined"
.

For example,

<section><p>hello</p><section>
works fine but
<section><p>hello <em>there</em></p><section>
fails to render.

Check out the code example below and view the fiddle. (Asynchronously simulated by setTimeout)

new Vue({
  el: '#app',
  data: {
    msg: 'simple template works',
    template: Vue.compile('<p>{{msg}}</p>').render
  },
  render(createElement) {
    return this.template();
  },
  mounted() {
    // Note that the below snippet fails
    setTimeout(()=>{
      this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep <em>fails</em>?</p></div>').render;
    }, 1000);
    // This one renders correctly
    setTimeout(()=>{
      this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep fails?</p></div>').render;
    }, 2000);
  }
})

Does anyone know what might be causing this issue? Are 'complex' templates supposed to be compiled/rendered differently?

Answer №1

When you use Vue.compile, it returns an object that contains two essential properties for rendering a component correctly. The first property is "render," which serves as the main render function for the template. The second property is "staticRenderFns," a set of functions generated during compilation to optimize the rendering process by handling static content.

In certain instances where no static render functions are created during compilation, your code may still function without including them. However, in general, both properties are necessary for proper rendering.

Below is an updated version of your code that should work:

console.clear()

new Vue({
  el: '#app',
  data: {
    msg: 'simple template works',
    template: Vue.compile('<p>{{msg}}</p>')
  },
  render(createElement) {
    let msg = this.msg
    let base = {
      data(){
        return {
          msg
        }
      }
    }
    let component = Object.assign({}, this.template, base)
    return createElement(component);
  },
  mounted() {
    setTimeout(()=>{
      this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep <em>fails</em>?</p></div>');
    }, 1000);
    
    setTimeout(()=>{
      this.template = Vue.compile('<div><p>{{msg}}</p><p>Nesting more than three tags deep fails?</p></div>');
    }, 2000);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app"></div>

For more information on Vue.compile, you can refer to the official documentation. Additionally, there is some documentation available here.

Linus Borg, a core team member of Vue, provides insights on staticRenderFns in this forum post:

Static Render Functions play a crucial role in optimizing the render process by caching static parts of the DOM tree. These functions cannot be updated or accessed during runtime but are essential components called by the render function when needed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having difficulty receiving a response from an AJAX call within the success function

After browsing through this stack link Ajax response not calling success:function() when using jQuery 1.8.3, I'm puzzled as to why the success function is not invoked when I uncomment the dataType line. It seems that setting dataType = JSON prevents t ...

What is the best way to display two array lists in JSON format and view them in data table rows using ASP.NET MVC?

There are two array lists, RoleList and EmpList. How can I return both arrays in JSON format and display them in rows on a data table? In order to return both arrays, you can use the following code snippet: return Json(EmpList,RoleList, JsonRequestBehavio ...

Rendering EJS Template Views Dynamically Based on Conditions within the Same Path

Hey there, I have a question as a complete beginner. I've been searching for hours and can't seem to find a solution for my specific issue (I'm sure it's something simple). I am working with data from an sqlite database table, filterin ...

Adjusting sort-icon properties in v-data-table does not produce the desired results

Although I have tried changing the sort-icon props, the icon itself does not update, but strangely it works on codepen. The current sort icon is still mdi-arrow-up, but I would like to change it to mdi-unfold-more-horizontal. <v-data-table @click:ro ...

<FormattedMessage /> extract text from within tags

I'm struggling to articulate this issue clearly. Currently, I am utilizing a Bootstrap Table to showcase my data which includes search filters, sorting, and other functionality. As I began working on internationalization, I initially formatted direc ...

Organizing DIVs upon website initialization

My website features a layout with three columns: <div id="column1"></div> <div id="column2"></div> <div id="column3"></div> I currently have 3 divs on the webpage: <div id="1">aaa</div> <div id="2">b ...

After entering the author's name in the text box, I am attempting to showcase a quote, but inexplicably, nothing is appearing. What steps should I take to resolve this issue

Every time I enter the author's name in the text box and hit the button to show the quote, it shows undefined. It appears that my button and textbox are not properly connected. How can I resolve this issue? <!DOCTYPE html> <html lang="en ...

Deactivated a specific radio button with a particular class attribute

Is there a way to disable radio buttons with a specific class using JavaScript? I attempted the following code: if( $("input[type=radio]").hasClass("class-full") ){ $(this).attr('disabled', true); } However, it does not seem to be effective ...

Displaying particles in system

I'm utilizing the Three.js ParticleSystem to showcase a large number of points, which greatly improves performance. At certain zoom levels, the particles may appear very close together, leading to the appearance of strange De Moivre fringes when adju ...

What could be the reason for the malfunctioning of the Angular options tracking by ID feature?

I seem to be facing an issue with my code: There is an object that holds the id of an item, along with an array containing these items. I require a 'select' element to display the currently selected item and allow for changing the selection. Th ...

Tips for sending a Postgres Pool or Client over a socket

After deploying my server to Heroku, I encountered an issue with sending a request to my Raspberry Pi for running a scraping function and updating a table in the Heroku Postgres database. The problem seems to be related to the client.query() function not b ...

What are the steps to change the rendering order of Vue components in mobile view?

I have implemented 2 Vue components that split the page into two sections: left side and right side. These components are utilized on every page with the following structure: <template> <div class="page-body"> <left-side> < ...

Sharing parameters between functions in JavaScript

I have a working code but I want to modify the function getLocation to accept 2 arguments that will be passed to getDistanceFromLatLonInKm within the ajmo function. Currently, getDistanceFromLatLonInKm has hardcoded arguments and I would like to use variab ...

Incorporating a new parameter into the JSON response from SoundCloud

Currently, I am in the process of developing an app utilizing the SoundCloud JavaScript API. My approach involves fetching the JSON data from: http://api.soundcloud.com/resolve.json?url=http://soundcloud.com/matas/hobnotropic&client_id=YOUR_CLIENT_ID ...

Sorting complex functions in React with Javascript

Looking to implement a sorting function that switches between descending (dsc) and ascending (asc) order. It should specifically handle sorting by the table column named "header". The objective is to sort either by "days" or "station" while toggling betwee ...

Error message for Laravel Passport authentication failure

I've been stuck on this issue for a while now and can't seem to pinpoint the problem. I am using Laravel on the backend and Vue on the front end. Logging in works fine, I receive the token, but when I try to access a route with auth:api, I get an ...

How to redirect from a method in Vue.js using Vue-router versions older than 1.x.x

While I don't consider myself a frontend developer, my knowledge of JavaScript is sufficient to complete basic tasks. Currently, I am working on integrating a login feature into my application, and I'm facing some challenges with my Vue component ...

How to open a hyperlink in a separate background tab with JavaScript or jQuery

I am in need of a feature that automatically opens all links on a website in a new background tab when a user clicks on them. Despite searching extensively, I have not found a solution that works across all browsers. To implement this, I have referred to t ...

Objects being collected as arrays of arrays in garbage collection

I recently came across an article stating that a simple delete is not sufficient to release memory allocated for an object. In my current scenario, I have an Object with several subOjects structured like this: MyObject[idx]['foo']. Is there a me ...

When trying to generate a list in Vue.js using Vuetify, an error occurred stating that it is best to steer clear of using a JavaScript keyword such as "v

Attempting to generate a basic list in Vue.js using Vuetify, I encountered an error message: Avoid using JavaScript keyword as "v-on" value: "" vue/valid-v-on. Can someone provide a detailed response, considering my limited knowledge of Vuetify and Vue.js? ...