Я получаю следующую ошибку в 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>
Я следил за примерами здесь: https://stackoverflow.com/a/39519105 и мой RenderPost.vue
примерно выглядит так:
<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>
Я добавил <client-only>
, потому что я также получал ошибку о том, что сервер и клиент не совпадают. Без него я получаю дополнительную ошибку, которая говорит:
[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.
Если я понимаю ваш комментарий, динамическому компоненту нужно имя, я добавил его в вопрос, не устраняет ошибку. Связанный пример, похоже, не имеет имени.
@Н.Б. На самом деле, <component>
поддерживает определение вычисляемого компонента, как это делает OP. Ошибка связана с тем, что используются строковые шаблоны, а сборка не настроена на использование полной сборки Vue, включающей компилятор.
Фрагмент ниже показывает, как работает <component :is = "dynamicComponent"></component>
.
Vue
(глобально):is
обновляется одним из зарегистрированных имен компонентовVue.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.info('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>
Nuxt обычно включает только среду выполнения Vue (исключая компилятор) в качестве оптимизации, которая уменьшает размер сборки примерно на 10 КБ, поскольку большинство пользователей используют предварительно скомпилированные шаблоны (например, с помощью отдельных файловых компонентов). Сборка Vue только для среды выполнения выдает предупреждение, которое вы наблюдаете, когда во время выполнения используются шаблоны в DOM или строки.
Поскольку вашему приложению требуются строковые шаблоны во время выполнения, вам необходимо настроить Nuxt для использования сборки Vue, которая включает компилятор:
// nuxt.config.js
export default {
build: {
extend(config) {
config.resolve.alias.vue = 'vue/dist/vue.common'
}
},
}
Динамический компонент принимает имя компонента, а не шаблон для рендеринга. Вы регистрируете компонент, назовем его
RenderPost
. Чтобы динамически отображать его через динамический компонент, вы должны использовать<component is = "RenderPost" />
. Кроме того, вы также можете указать параметры, используя<component is = "RenderPost" v-bind = "{key: value}" />