Subscribe on changes!

Warning using compile() in render() on method calls

avatar
Mar 17th 2023

Vue version

3.2.45

Link to minimal reproduction

https://codesandbox.io/s/fervent-platform-8m2hlu?file=/src/components/ContentRender.vue

Steps to reproduce

I have a component whose template is compiled dynamically through the compile() function. The use case is an online vue-based IDE which gives a real time preview of edited fragments.

It works great so far, except for the following warning. I get it twice for every time the compiled template uses a component method:

[Vue warn]: Property undefined was accessed during render but is not defined on instance.

Here is a minimal component which triggers the issue:

<script>
import { compile } from "vue";
export default {
  name: "ContentRender",
  methods: {
    hello: function (x) {
      return `hello ${x}`;
    },
  },
  render: function (vm) {
    const template = `<div :title="hello('world')">
      {{hello('world')}},
      {{hello('world')}},
      {{hello('world')}}
    </div>`;
    const compiledTemplate = compile(template);
    return compiledTemplate(vm);
  },
};
</script>

It can be observed here: https://codesandbox.io/s/fervent-platform-8m2hlu?file=/src/components/ContentRender.vue

What is expected?

Execution with no warning is expected.

What is actually happening?

Following warning appears twice for every component method call:

[Vue warn]: Property undefined was accessed during render but is not defined on instance.

The method calls otherwise resolve successfully.

System Info

No response

Any additional comments?

No response

avatar
Mar 18th 2023

There is more than one way to compile in vue.js. I tried a different approach and it worked, but it might be far different than you want. You might be able to refactor it to something useful. I changed the files main.js, ContentRender.vue and App.vue
https://codesandbox.io/s/pedantic-kowalevski-3d2jb7?file=/src/components/ContentRender.vue

avatar
Mar 18th 2023

I’m resorting to using compile() instead of the usual approach because the template is only known at runtime. It’s a Laravel+Inertia+Vite application where the users edit the template themselves. They’re stored and pulled from database.

In the full app, ContentRender receives its template as a prop, like this:

https://codesandbox.io/s/recursing-bell-gorsu5?file=/src/components/ContentRender.vue

avatar
Mar 18th 2023

I should have used my wording correctly. Still used a compiler but in a different way. I used the compileToFunction. To get it working your way using theimport { compile } from "vue" perhaps the best way is to get the most simple working example of vue using a compiler. Perhaps there is a unit test already in this project you can use. Then build code around it until either the bug occurs where you can isolate it or the code is complete without errors. I will have a bash at it in a few hours time.

avatar
Mar 18th 2023

@toomsie Oh OK, you moved the runtime compilation to App.vue instead with a call to compileToFunction(). It’s not being called though, because render() isn’t. This is because you kept the template. If we remove the template, render() gets properly executed and I get this error: _vue.compileToFunction is not a function

https://codesandbox.io/s/romantic-dust-xf2ybz?file=/src/App.vue

avatar
Mar 18th 2023

I will tidy this up be as close to your original example. Truth is I barely know anything about vue.js

avatar
Mar 18th 2023

Thanks for having a look. Hopefully someone knowledgeable about vue will chime in as well.

avatar
Mar 18th 2023

Ok, I have created a hello world example of my own. Later today I will make it close to your example and hopefully I might even be able to tell you why the error happened. https://codesandbox.io/s/intelligent-sea-lwtdwy?file=/src/components/ContentRender.vue

avatar
Mar 18th 2023

The code looks like your code. But I am not sure if the template is indirectly compiled or not. via the const template = this.$options.template;

https://codesandbox.io/s/saturday-18-f7welb?file=/src/App.vue

avatar
Mar 20th 2023

This is fixed in Vue 3.3.0-alpha.4.

avatar
Mar 20th 2023

Very nice. I guess we should have tested the code in different versions 😒.

avatar
May 29th 2023
image image
avatar
Jun 1st 2023
image