首页 > 解决方案 > 如何根据条件将模板代码块包装在不同的元素中?

问题描述

我的组件有 2 个道具:linkisExternal. 根据后者,我将把我的模板代码包装在一个<NuxtLink(相当于 native Vue <router-link>)或一个<a>元素中。

下面的代码通过使用两次相同的模板代码来实现这一点——这显然很糟糕。

然而我想不出一种简单的方法来优雅地做到这一点。任何想法?

<template>
  <NuxtLink
    v-if="!isExternal"
    to="link"
  >
    <div
      class="btn"
      :style="{
        'background-color': backgroundColor,
        'color': textColor
      }"
    >
      <img
        v-if="image"
        :src="image"
        class="image"
      >

      <div>{{ text }}</div>

      <svg-icon name="arrow-right" class="arrow" />
    </div>
  </NuxtLink>

  <a
    v-else
    href="link"
    target="_blank"
  >
    <div
      class="btn"
      :style="{
        'background-color': backgroundColor,
        'color': textColor
      }"
    >
      <img
        v-if="image"
        :src="image"
        class="image"
      >

      <div>{{ text }}</div>

      <svg-icon name="arrow-right" class="arrow" />
    </div>
  </a>
</template>

标签: vue.jsnuxt.jsrouterlink

解决方案


您可以使用component这样的元素:

<template>
  <component
    :is="computedTag"
    v-bind="computedProps"
  >
    <div
      class="btn"
      :style="{
        'background-color': backgroundColor,
        'color': textColor
      }"
    >
      <img
        v-if="image"
        :src="image"
        class="image"
      >

      <div>{{ text }}</div>

      <svg-icon name="arrow-right" class="arrow" />
    </div>
  </component>
</template>

<script>
export default {
  props: ['link', 'isExternal'],
  computed: {
    computedTag() {
      return this.isExternal ? 'a' : 'nuxt-link';
    },
    computedProps() {
      return this.isExternal
        ? { href: this.link, target: '_blank' }
        : { to: this.link };
    },
  },
};
</script>

推荐阅读