Reputation: 1813
I'm getting the following error in Nuxt.js:
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
found in
---> <Anonymous>
<RenderPost> at components/RenderPost.vue
<Pages/post/Id.vue> at pages/post/_id.vue
<Nuxt>
<Layouts/default.vue> at layouts/default.vue
<Root>
I was following the examples here: https://stackoverflow.com/a/39519105 and my RenderPost.vue
roughly looks like this:
<template>
<client-only>
<component :is="dynamicComponent" />
</client-only>
</template>
<script>
export default {
methods:
{
linkedView()
{
return `<a href="#" @click.prevent="runSomething">Click me</a>`;
},
},
computed :
{
dynamicComponent() {
return {
data() { return { foo : null }},
template : `<div>${this.linkedView()}<br>{{ foo }}</div>`,
methods :
{
runSomething()
{
this.foo = 'ran something!'
}
}
}
}
}
}
</script>
I added the <client-only>
because I was also getting error about server and client not matching up. Without it, I get an additional error that says:
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
Upvotes: 2
Views: 2575
Reputation: 138286
Nuxt normally includes the Vue runtime only (excludes the compiler) as an optimization that reduces the build size by ~10KB, as most users employ precompiled templates (e.g., via single file components). The Vue runtime-only build emits the warning you're observing when in-DOM or string templates are used at runtime.
Since your app requires string templates at runtime, you'll need to configure Nuxt to use the Vue build that includes the compiler:
// nuxt.config.js
export default {
build: {
extend(config) {
config.resolve.alias.vue = 'vue/dist/vue.common'
}
},
}
Upvotes: 3
Reputation: 8329
The snippet below shows how <component :is="dynamicComponent"></component>
works.
Vue
(globally):is
binding is updated with one of the registered component namesVue.component('Comp1', {
template: `
<div>
COMPONENT 1<br />
<button
@click="() => $emit('clicked', 1)"
>
Click 1
</button>
</div>
`
})
Vue.component('Comp2', {
template: `
<div>
COMPONENT 2<br />
<button
@click="() => $emit('clicked', 2)"
>
Click 2
</button>
</div>
`
})
new Vue({
el: "#app",
data() {
return {
dynamicComponent: 'Comp1'
}
},
methods: {
toggleComponent() {
if (this.dynamicComponent === 'Comp1') {
this.dynamicComponent = 'Comp2'
} else {
this.dynamicComponent = 'Comp1'
}
},
handleClicked(id) {
console.log('click in comp', id)
}
},
template: `
<div>
<button
@click="toggleComponent"
>
SWITCH COMPONENT
</button>
<br />
<component
:is="dynamicComponent"
@clicked="(id) => handleClicked(id)"
></component>
</div>
`
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
Upvotes: 0