Vue. js: лучший способ для перехода элементов без одновременного использования v-for и v-if? - PullRequest
2 голосов
/ 22 января 2020

Я использую v-for для создания нескольких <p> элементов. v-for обернут компонентом Vue <transition>, потому что я хочу, чтобы каждый <p> анимировался, если выполняется условие v-if. Вот этот код ниже:

<transition name="fade">
  <p
    v-for="(quote, idx) in game.quotes" <-- game.quotes comes from VUEX
    :key="`game-quote-${idx}`"
    class="quote-box__current_quote"
    v-if="game.currentQuoteIdx === idx"
  >"{{ quote.content }}"</p>
</transition>

Однако я получаю ошибки ESLINT из-за правила vue/no-use-v-if-with-v-for.

После исследования этого правила мне было указано на следующее руководство по стилю Vue: https://vuejs.org/v2/style-guide/#Avoid -v-if-with-v-for-essential . Руководство рекомендует избегать использования v-for и v-if на одном элементе. Я хотел бы анимировать каждый элемент ввода / вывода с помощью компонента оболочки <transition> (только один тег <p> должен быть виден одновременно). Есть ли более идеальный способ добиться того, что я делаю, без использования v-if и v-for на одном элементе?

Дополнительная проблема: я получаю следующую ошибку в отношении game.quotes в v-for="(quote, idx) in game.quotes":

The 'undefined' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.

game.quotes исходит от Vuex, и массив не нуждается в фильтрации. Почему ESLINT рекомендует создавать вычисляемое свойство и возвращать отфильтрованный массив?

FILE ON GITHUB - строка 10

Ответы [ 3 ]

1 голос
/ 22 января 2020

Создать вычисляемое свойство и вернуть отфильтрованный массив. Это потому, что ваш код похож на фильтрацию массива из-за того, что v-if присоединен к вашему v-for. Короче говоря, вы просто фильтруете элемент, который хотите отобразить в вашем l oop. Почему бы не использовать вычисленные свойства ? Это безопасно и легко в обращении.

1 голос
/ 22 января 2020

Возьмите этот пример, который очень похож на ваш: не показывайте li, которые не нужны. Сочетание v-for и v-if прекрасно работает, если не лучшая практика. Однако есть более простой способ.

<h2>Items:</h2>
<ol id="list">
  <li v-for="item in items" v-if="visible.includes(item)" :id="'item-'+item">
    {{ item }}
  </li>
</ol>

https://jsfiddle.net/oLjuy5bv/1/

Что мы можем сделать вместо этого, так как в двух других состояниях ответа создается вычисляемый метод и вычислите список для v-for и удалите v-if.

<h2>Items:</h2>
<ol id="list">
  <li v-for="item in visible_items" :id="'item-'+item">
    {{ item }}
  </li>
</ol>

computed: {
  visible_items () {
    return this.items.filter(item => this.visible.includes(item))
  }
},

https://jsfiddle.net/17Ln5mw8/

То, что вы ищете, то является чем-то вот так, который использует метод из-за контекста idx и, возможно, game (я не знаю логики c конкретно):

<transition name="fade">
  <p
    v-for="(quote, idx) in gameQuotesByIdx(idx)"
    :key="`game-quote-${idx}`"
    class="quote-box__current_quote"
  >"{{ quote.content }}"</p>
</transition>

methods: {
  gameQuotesByIdx(idx) {
    return ...
  }
},

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

1 голос
/ 22 января 2020

Официальная документация гласит, что весь условный рендеринг внутри циклов должен выполняться с помощью computed функций. Сделайте условное просеивание в вычисленном (полученное из геттера, если вы используете Vuex), а затем поместите это в шаблон.

Официальное руководство по стилю для этого: https://vuejs.org/v2/style-guide/#Avoid -v-if- с V-для-эссенциальной

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