如何根据条件将模板代码块包装在不同的元素中?
How to wrap a block of template code in different elements depending on a condition?
我的组件有 2 个属性:link
和 isExternal
。根据后者,我会将我的模板代码包装在 <NuxtLink
(相当于本机 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>
您可以像这样使用 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>
我的组件有 2 个属性:link
和 isExternal
。根据后者,我会将我的模板代码包装在 <NuxtLink
(相当于本机 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>
您可以像这样使用 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>