Nuxt - шаблон root требует ровно один элемент - PullRequest
1 голос
/ 13 февраля 2020

Я недавно обновил несколько зависимостей в проекте на основе Nuxt, над которым у меня работал разработчик (я дизайнер с очень большой базой знаний c JS / vue). Теперь сборка выплевывает сообщение «шаблон root требует ровно один элемент». Из поиска других потоков я вижу принцип того, что мне нужно изменить (содержать все в одном элементе), но я просто не уверен, как это сделать с определенной структурой этих файлов (расположение v-if). Я включил оскорбительный файл ниже и задавался вопросом, может ли кто-нибудь указать мне правильное направление? Очень ценится!

<template>
  <nuxt-link
    v-if="to"
    :class="classes"
    :to="to"
    v-bind="inheritedProps"
    v-on="$listeners"
  >
    <slot />
  </nuxt-link>

  <a
    v-else-if="href"
    :class="classes"
    :href="href"
    v-bind="inheritedProps"
    v-on="$listeners"
  >
    <slot />
  </a>

  <button
    v-else
    :class="classes"
    :type="type"
    v-bind="inheritedProps"
    v-on="$listeners"
  >
    <slot />
  </button>
</template>

<script>
export default {
  name: 'BaseButton',
  props: {
    block: {
      type: Boolean,
      default: false
    },
    variant: {
      type: String,
      default: () => {}
    },
    href: {
      type: String,
      default: () => {}
    },
    to: {
      type: String,
      default: () => {}
    },
    type: {
      type: String,
      default: () => {}
    }
  },
  computed: {
    inheritedProps () {
      return {
        ...this.$props,
        ...this.$attrs
      }
    },
    classes () {
      return [
        'btn',
        {
          'btn--block': this.block
        }
      ].concat(this.modifiers)
    },
    modifiers () {
      const modifiersArray = this.variant && this.variant.split(' ')
      return this.variant ? modifiersArray.map(modifier => `btn--${modifier}`) : false
    }
  }
}
</script>

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Я немного удивлен, что вы видите эту ошибку, поскольку Vue обычно не жалуется, если вы используете v-if / v-else-if / v-else таким образом. Шаблон гарантированно выводит отдельный элемент при запуске, поэтому обычно Vue это позволяет. Это может пролить больше света на то, что происходит, если вы включите в вопрос точное сообщение об ошибке.

Я предлагаю проверить, не сталкиваетесь ли вы с проблемой, описанной ниже, вызванной несовместимыми версиями библиотеки, которая неправильно сообщает об этом ошибка:

https://github.com/vuejs/eslint-plugin-vue/issues/986

Я действительно не думаю, что с вашим кодом что-то не так, поэтому я предлагаю изучить версии библиотеки, прежде чем вносить какие-либо изменения в код.

Далее, если жалуется только линтер, вы можете рассмотреть возможность подавления этого правила. Шаблонный компилятор Vue выкрикнет достаточно быстро, если возникнет реальная проблема с несколькими root узлами.

Тем не менее, если вы действительно не можете сделать сообщение об ошибке go прочь ...

Самое простое решение - просто обернуть все в дополнительный элемент в root.

Если вы не хотите использовать элемент-обертку (возможно, потому что он мешает вашему макету), вы можете используйте is, чтобы уменьшить ваш шаблон:

<template>
  <component
    :class="classes"
    v-bind="childProps"
    v-on="$listeners"
  >
    <slot />
  </component>
</template>

<script>
export default {
  // ... other stuff ...

  computed: {
    childProps () {
      const childProps = {...this.inheritedProps}

      if (this.to) {
        childProps.is = 'nuxt-link'
        childProps.to = this.to
      } else if (this.href) {
        childProps.is = 'a'
        childProps.href = this.href
      } else {
        childProps.is = 'button'
        childProps.type = this.type
      }

      return childProps
    }
  }
}
</script>

Тем не менее, вы почти на render функциональной территории, делая это таким образом.

1 голос
/ 13 февраля 2020

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

вы можете использовать нижеприведенное решение

<template>
<div>
  <nuxt-link
    v-if="to"
    :class="classes"
    :to="to"
    v-bind="inheritedProps"
    v-on="$listeners"
  >
    <slot />
  </nuxt-link>

  <a
    v-else-if="href"
    :class="classes"
    :href="href"
    v-bind="inheritedProps"
    v-on="$listeners"
  >
    <slot />
  </a>

  <button
    v-else
    :class="classes"
    :type="type"
    v-bind="inheritedProps"
    v-on="$listeners"
  >
    <slot />
  </button>
</div>
</template>
...