1

I created the following functional component using render method:

import Vue from "vue"

const { render, staticRenderFns } = Vue.compile(`<div>Hello World</div>`)

Vue.component("HelloWorld", {
    functional: true,
    render,
    staticRenderFns
})

And then in App.vue:

<template>
    <div id="app">
        <HelloWorld />
    </div>
</template>

<script>
export default {
    data() {
        return {
            compiled: false
        }
    }
}
</script>

<style>
</style>

And I get the error:

_c is not defined.

Am I doing something wrong here?

4
  • See this - stackoverflow.com/questions/44369839/… you need to import your component Commented Nov 14, 2019 at 8:47
  • Import my component? But it's already declared as a global component. And also, this issue is only with the functional component. Normal component works fine i.e. if I remove functional: true it works fine. Commented Nov 14, 2019 at 8:55
  • 1
    How about: stackoverflow.com/questions/57901607/… Commented Nov 14, 2019 at 13:57
  • 2
    @webnoob Damn that's useful. Thank you very much. Although not sure about functional component. Commented Nov 15, 2019 at 3:43

3 Answers 3

0

As far as I'm aware, the render functions generated by Vue.compile cannot be used to render a functional component.

Sign up to request clarification or add additional context in comments.

6 Comments

Oh crap! That's a bummer. Is there any way to build functional component by passing template string?
I don't think so. The template compiler bundled with Vue is not able to compile functional templates. I believe only the compiler provided with vue-loader can do this at build time.
May I ask why you require the use of Vue.compile? Maybe there's a better solution to your problem.
Actually I fetch html from the server and render it as a Vue component.
Is what you're fetching plain HTML or is it a Vue template? If it's sanitized HTML then you can just use v-html to render it.
|
0

I think the closest thing to creating a functional component from a template string would involve parsing the string to get the element type and attributes and render as:

Vue.component("hello-world", {
      functional: true,
      render: function(createElement, context) {
        return createElement(
          "div",
         'example text'         
        );
      }
});

Comments

0

As Decade Moon already mentioned, render functions returned by Vue.compile cannot be used as render function in functional component. Reason for that becomes clear when you inspect the signature of the function returned by Vue.compile:

const render: (createElement: any) => VNode

As you can see, function is missing second argument, which is required for render functions of functional components:

render: (createElement: CreateElement, context: RenderContext<Record<never, any>>) => VNode

Functional components are instanceless. That means no this context - that's why additional context parameter is needed to carry props\listeners etc.

Also if you look at this post on Vue forum:

The render function created by compile() relies on private properties of the component. To have access to those properties, the method has to be assigned to a property of the component(so it has access to those properties via this)

However that doesn't mean you can't create functional component with template. You can, you are just not able to use Vue.compile to pass template text dynamically. If you are fine with static template, you can do it like this:

// component.vue

<template functional>
  <div>Hello World</div>
</template>

<script>
export default {
  name: "hello"
};
</script>

...and use the component like any other SFC (single file component = VUE file)

If you need dynamic template text, just use non-functional component instead...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.