【问题标题】:Nuxt - The template root requires exactly one elementNuxt - 模板根只需要一个元素
【发布时间】:2020-05-28 15:57:09
【问题描述】:

我最近更新了一个基于 Nuxt 的项目中的一些依赖项,我有一个开发人员为我工作(我是一名具有非常基本的 JS/vue 知识库的设计师)。现在构建吐出“模板根需要一个元素”错误。通过搜索其他线程,我可以看到我需要更改的原则(包含一个元素中的所有内容),但我只是不确定如何使用此文件的特定结构(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>

【问题讨论】:

    标签: vue.js nuxt.js eslint


    【解决方案1】:

    我有点惊讶你看到这个错误,因为如果你像这样使用v-if/v-else-if/v-else,Vue 通常不会抱怨。模板保证在运行时输出单个元素,因此通常 Vue 允许这样做。如果您在问题中包含确切的错误消息,它可能会更清楚地说明发生了什么。

    我建议检查你没有遇到下面讨论的问题,由不兼容的库版本引起,错误地报告这个错误:

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

    我真的不认为你的代码有什么问题,所以我建议在进行任何代码更改之前调查库版本。

    此外,如果只是 linter 在抱怨,您可以考虑取消该规则。如果存在多个根节点的真正问题,Vue 模板编译器会很快大喊大叫。

    也就是说,如果你真的不能让错误信息消失......

    最简单的解决方案是将所有内容包装在根的额外元素中。

    如果您不想使用包装器元素(可能是因为它会干扰您的布局),您可以使用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 功能领域这样做。

    【讨论】:

    • 非常感谢裙子。确实是不兼容的 es-lint 版本。欣赏您的替代品的范围。
    【解决方案2】:

    您应该将模板下的所有内容包装到根 tag 中,例如我使用 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>
    

    【讨论】:

      猜你喜欢
      • 2021-10-01
      • 1970-01-01
      • 2021-02-28
      • 2017-03-18
      • 2019-03-22
      • 2015-03-15
      • 2018-02-10
      • 2017-09-20
      • 2021-08-12
      相关资源
      最近更新 更多