Условное отображение оболочки в vue - PullRequest
0 голосов
/ 04 февраля 2020

Я делаю компонент ссылки / кнопки, который может иметь кнопку или оболочку привязки, текст и необязательный значок. Мой код шаблона ниже в настоящее время отображает либо привязку, либо кнопку (с точно таким же содержимым) на основе оператора if для элемента оболочки, что приводит к дублированию кода.

<template>
    <a v-if="link" v-bind:href="url" class="btn" :class="modifier" :id="id" role="button" :disabled="disabled">
        {{buttonText}}
        <svg class="icon" v-if="icon" :class="iconModifier">
            <use v-bind="{ 'xlink:href':'#sprite-' + icon }"></use>
        </svg>
    </a>
    <button v-else type="button" class="btn" :class="modifier" :id="id" :disabled="disabled">
        {{buttonText}}
        <svg class="icon" v-if="icon" :class="iconModifier">
            <use v-bind="{ 'xlink:href':'#sprite-' + icon }"></use>
        </svg>
    </button>
</template>

Есть ли более чистый способ за завершение моего buttonText и значка внутри якоря или кнопки?

Ответы [ 3 ]

0 голосов
/ 04 февраля 2020

Есть несколько способов сделать это. В качестве примера можно привести два примера:

  1. Вы определяете два разных компонента (Button или Anchor) и хотите использовать оболочку для визуализации любого из них.

    • Вы можете разделить Содержимое Обертки на два компонента, чтобы обертка только решала, какой из компонентов будет отображаться (Кнопка или Якорь).
    • Проблема с этим подходом может быть, у вас будет двойной код для методов и стилей для компонента кнопки и привязки.
  2. Вы определяете содержимое как компонент и используете оболочку, чтобы определить, что переносить содержание в.

Было бы здорово узнать, почему вы хочу достичь этого. Может быть, есть лучшие решения для вашего использования. Ура!

0 голосов
/ 18 февраля 2020

Я решил свою проблему с помощью интенсивного поиска в Google! Найдена эта проблема относительно Vue на Github, которая указала мне правильное направление.

Небольшой фрагмент предыстории

Я использую Vue в сочетании с Storybook создать библиотеку компонентов, в которой кнопка может быть кнопкой или якорем. Все кнопки выглядят одинаково (кроме цвета) и могут быть использованы для отправки или ссылки. Чтобы упорядочить структуру папок, я бы хотел, чтобы решение генерировало несколько типов кнопок (со ссылкой или без) из одного файла.

Решение

Использование вычисляемых свойств Я могу "вычислить" необходимый тег, основываясь на свойстве url моего компонента. Когда передается url, я знаю, что моя кнопка должна ссылаться на другую страницу. Если свойство url отсутствует, оно должно отправлять что-либо или предварительно настраивать пользовательский обработчик щелчков (нет в приведенном ниже примере кода).

Я создал вычисляемое свойство returnComponentTag, чтобы избежать размещения сложных или громоздких объектов. logi c (как и мое оригинальное решение) в моем шаблоне. Возвращает тег a или button в зависимости от наличия свойства url.

Далее, как предлагает ajobi, используя атрибут :is, я могу определить тег компонента на основе результата моего вычисляемого свойства. Ниже приведен пример моего окончательного (и рабочего) решения:

<template>
    <component :is="returnComponentTag" v-bind:href="url ? url : ''" class="btn" :class="modifier" :id="id">
        {{buttonText}}
    </component>
</template>

<script>
export default {
    name: "Button",
    props: {
        id: {
            type: Number
        },
        buttonText: {
            type: String,
            required: true,
            default: "Button"
        },
        modifier: {
            type: String,
            default: "btn-cta-01"
        },
        url: {
            type: String,
            default: ""
        }
    }, 
    computed: {
        returnComponentTag() {
            return this.url ? "a" : "button"
        }
    }
};
</script>
0 голосов
/ 04 февраля 2020

Вы можете извлечь упаковочный элемент в выделенный компонент.

<template>
    <a v-if="link" v-bind:href="url" class="btn" :class="modifier" :id="id" role="button" :disabled="disabled">
        <slot></slot>
    </a>
    <button v-else type="button" class="btn" :class="modifier" :id="id" :disabled="disabled">
        <slot></slot>
    </button>
</template>

// You would use it like this

<SomeComponent /* your props here */ >
    {{buttonText}}
    <svg class="icon" v-if="icon" :class="iconModifier">
        <use v-bind="{ 'xlink:href':'#sprite-' + icon }"></use>
    </svg>
</SomeComponent>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...