Ошибка динамического компонента Nuxt.js «Либо предварительно скомпилируйте шаблоны в функции рендеринга, либо используйте сборку, включаемую компилятором»

Я получаю следующую ошибку в 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.

Динамический компонент принимает имя компонента, а не шаблон для рендеринга. Вы регистрируете компонент, назовем его RenderPost. Чтобы динамически отображать его через динамический компонент, вы должны использовать <component is = "RenderPost" />. Кроме того, вы также можете указать параметры, используя <component is = "RenderPost" v-bind = "{key: value}" />

N.B. 11.12.2020 15:44

Если я понимаю ваш комментарий, динамическому компоненту нужно имя, я добавил его в вопрос, не устраняет ошибку. Связанный пример, похоже, не имеет имени.

Robert C. Holland 11.12.2020 15:55

@Н.Б. На самом деле, <component> поддерживает определение вычисляемого компонента, как это делает OP. Ошибка связана с тем, что используются строковые шаблоны, а сборка не настроена на использование полной сборки Vue, включающей компилятор.

tony19 12.12.2020 08:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
2 049
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Фрагмент ниже показывает, как работает <component :is = "dynamicComponent"></component>.

  • 2 компонента зарегистрированы в 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'
    }
  },
}

Другие вопросы по теме