Сохранение условного оператора v-if в объекте в Vue.js

Можно ли сохранить условный оператор в объекте и динамически добавлять его?

Например, у меня есть такой код, который выводит строку таблицы с кнопкой в ​​ней:

 <tr v-for = "item in items">
     <td><button v-if = "item.display">{{item.name}}</button>
 </tr>

Это мои данные, которые я возвращаю

data() {
        return {
            items : [
                {
                    name : 'Item1',
                    display : 'price >= 5',
                },
                {
                    name : 'Item2',
                    display : 'price == 10',
                },
            ],
        }
    },

При этом логика не работает. Кнопка отображается всегда.

Однако, если бы мне пришлось вручную вводить эту логику для каждой кнопки. Работает корректно. Например, это работает:

<tr v-for = "item in items">
     <td><button v-if = "price >= 5">{{item.name}}</button>
 </tr>

Итак, в конце концов, мой вопрос. Может ли условный оператор храниться таким образом и динамически добавляться, или Vue не распознает его таким образом?

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
0
1 995
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Технически вы можете использовать функции как свойства ваших объектов и вызывать их:

new Vue({
  el: '#app',
  data() {
    return {
      price: 5,
      items: [{
          name: 'Item1',
          display: (price) => price >= 5,
        },
        {
          name: 'Item2',
          display: (price) => price == 10,
        },
      ],
    }
  }
})
<script src = "https://unpkg.com/vue"></script>

<div id = "app">
  Type "10": <input v-model = "price">
  <table>
    <tr v-for = "item in items">
      <td><button v-if = "item.display(price)">{{item.name}}</button>
    </tr>
  </table>
</div>

Но, возможно, более подходящим подходом Vueу было бы указать ограничения отображения в объекте и иметь расчет в метод.

Преимущество здесь в том, что ваши данные items легко сериализуемы (например, в JSON), тогда как в приведенном выше варианте это не так:

new Vue({
  el: '#app',
  data() {
    return {
      price: 5,
      items: [{
          name: 'Item1',
          display: {op: 'ge', val: 5},
        },
        {
          name: 'Item2',
          display: {op: 'eq', val: 10},
        },
      ],
    }
  },
  methods: {
  	display(item) {
    	switch(item.display.op) {
      	case 'eq': return this.price == item.display.val;
        case 'gt': return this.price > item.display.val;
        case 'lt': return this.price < item.display.val;
        case 'ge': return this.price >= item.display.val;
        case 'le': return this.price <= item.display.val;
        default: return false;
      }
    }
  }
})
<script src = "https://unpkg.com/vue"></script>

<div id = "app">
  Type "10": <input v-model = "price">
  <table>
    <tr v-for = "item in items">
      <td><button v-if = "display(item)">{{item.name}}</button>
    </tr>
  </table>
</div>

Я думаю, что acdcjunior дал хороший прямой ответ на этот вопрос. Я не уверен, стоит ли мне что-то здесь добавлять на тот случай, если вопрос был чисто техническим по этой конкретной функции Vue.

Однако я просто хочу заметить, что данные - не лучшее место для хранения отображаемой информации. Более распространенная ситуация, когда у вас есть данные с собственными ценами:

data() {
    return {
      price: 5,

      items: [{
          name: 'Item1',
          price: 5,
        },
        {
          name: 'Item2',
          price: 10,
        },
      ],
    }
  }

И очень распространенный случай, когда вам нужно отрендерить только часть ваших элементов. Этот сценарий хорошо описан в vue docs: https://vuejs.org/v2/guide/list.html#Displaying-Filtered-Sorted-Results

Надеюсь, это не было лишним :)

Кроме того, вернемся к самому вашему вопросу:

Can the conditional statement be stored like that and dynamically added in, or will Vue not recognize it that way?

Думаю, короткий ответ - «Нет».

Потому что, когда вы передаете item.condition (который является строкой) в v-if, результат оценки вашего выражения (например, "price === 5") будет проверяться на правильность -> и непустая строка всегда будет true. Для струнных аналогов eval не существует.

Но когда выражение является функцией (как в примере acdcjunior), результат его выполнения будет результирующим выражением, которое следует проверить.

Другие вопросы по теме