Условное поведение ссылки в VueJS - PullRequest
0 голосов
/ 12 сентября 2018

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

У меня есть компонент, который представляет карточку продукта. Весь компонент обернут в <router-link>, что приводит к странице продукта.

Однако у меня есть еще один случай, когда мне не нужен компонент для перехода на страницу продукта, а вместо этого мне нужно выполнить какое-то другое действие.

Единственное решение, которое я нашел, - передать функцию обратного вызова в качестве подпорки и, основываясь на этом, сделать что-то вроде:

<router-link v-if="!onClickCallback">
    ... here goes the whole component template ...
</router-link>
<div v-if="onClickCallback" @click="onClickCallback">
    ... here again goes the whole component template ...
</div>

Как я могу сделать это без копирования всего компонента? Я пытался сделать это (реальный пример кода):

  <router-link class="clothing-item-card-preview"
               :class="classes"
               :style="previewStyle"
               :to="{ name: 'clothingItem', params: { id: this.clothingItem.id }}"
               v-on="{ click: onClick ? onClick : null }">

Однако я получил это: Invalid handler for event "click": got null

Плюс не уверен, что можно передать модификатор prevent за клик, и это выглядит странно, должно быть лучшее архитектурное решение

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Комментируя ошибку, вы можете использовать пустую функцию вместо нуля в реальном фрагменте кода

  <router-link class="clothing-item-card-preview"
           :class="classes"
           :style="previewStyle"
           :to="{ name: 'clothingItem', params: { id: this.clothingItem.id }}"
           v-on="{ click: onClick ? onClick : null }">
0 голосов
/ 13 сентября 2018

Это должно работать (замените на «router-link», затем вставьте правильные свойства) Дополнительная информация:

  • https://fr.vuejs.org/v2/guide/components-dynamic-async.html
  • v-bind - это просто объект, в котором каждый ключ является реквизитом для вашего компонента, поэтому здесь я программно определил объект свойств в зависимости от оболочки (ссылка на маршрутизатор или простой div). Однако мы не можем сделать это для событий (конечно, мы могли бы создать нашего собственного слушателя событий, но это немного сложно), поэтому я просто использую метод handle.

new Vue({
    el: "#app",
    data: {
		  products : [{onClickCallback : () => { alert("callback"); return true;}}, {}, {}]
    },
    methods : {
        handleClick(product, event) {
            if (!product.onClickCallback) return false
            product.onClickCallback()
            return true
        },
        getMyComponentName(product) {
            if (product.onClickCallback) return "div"
            return "a"
        },

        getMyComponentProperties(product) {
            if (product.onClickCallback) return {is : "div"}
            return {
                is : "a",
                href: "!#"
            }
        }
    }
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
    <component
        v-for="(product, index) in products"
        :key="index"
        v-bind="getMyComponentProperties(product)"
        @click="handleClick(product, $event)"
    >
        <div class="product-card">
            <div class="product-card-content">
                <span v-show="product.onClickCallback">I'm a callback</span>
                <span v-show="!product.onClickCallback">I'm a router link</span>
            </div>
        </div>
    </component>
</div>
0 голосов
/ 12 сентября 2018

У вас есть для использования <router-link>?Если это может быть <div>, вы можете использовать что-то вроде

<div @click="handleClick" ...>
  <!-- component template -->
</div>

и

methods: {
  handleClick (event) {
    if (this.onClickCallback) {
      this.onClickCallback(event)
    } else {
      this.$router.push({ name: 'clothingItem', ... })
    }
  }
}

См. https://router.vuejs.org/guide/essentials/navigation.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...