Как реализовать <transition-group> внутри цикла v-for?

Есть один предлагаемый ответ на этот вопрос, но решение не работает для меня. У меня есть вложенный v-for, и я хотел бы анимировать самые внутренние элементы li по мере их удаления или добавления моим вычисляемым оператором. Мой текущий код выглядит так:

          <transition-group @before-enter="beforeEnter" @enter="enter" @leave="leave" tag="ul" v-if="computedProviders">
      <li v-for="(letter, index) in computedProviders" :key="index">
        <div>
          <p>{{index.toUpperCase()}}</p>
        </div>
        <transition-group :letter="letter" tag="ul" class="list" @before-enter="beforeEnter" @enter="enter" @leave="leave">
          <li v-for="provider in letter" :key="provider.last_name">
            <div>
              <a :href="provider.permalink">
                {{provider.thumbnail}}
              </a>

              <div>
                <h3>
                  <a :href="provider.permalink">
                    {{provider.last_name}}, {{provider.first_name}} <span>{{provider.suffix}}</span><br>
                    <p>{{provider.specialty}}</p>
                  </a>
                </h3>
              </div>
            </div>
          </li>
        </transition-group>
      </li>
    </transition-group>
  </div>

Внешняя группа перехода работает нормально, но когда я настраиваю внутреннюю, я получаю ReferenceError: буква не определена. Я попытался добавить: letter ="letter", как было предложено здесь , но у меня все еще не работает. Какие-либо предложения? Я счастлив переформатировать код, если есть более разумный способ.

2 ответа

Одно из предостережений при использовании шаблонов в DOM заключается в том, что браузер анализирует DOM до того, как Vue доберется до него. Браузер не знает, что <transition-group tag="ul">есть, так что это просто игнорируется. Вместо этого он видит внутри другого. Поскольку элементы обычно не могут быть вложенными, браузер поднимает <li v-for="provider in letter" :key="provider.last_name"> за пределами своего родителя <li> это определяет.

Удаление Vue и проверка DOM выявит проблему:

Когда Vue обрабатывает этот шаблон, он встречает letter, который технически не задекларирован за пределами v-for, в результате появляется ошибка, которую вы видите.

Решение 1: обертка

Если вам нужно использовать шаблоны в DOM, оберните внутренний <transition-group> с <template> так что браузер проигнорирует это:

      <transition-group tag="ul">
  <li v-for="(letter, index) in computedProviders" :key="index">
    <template> 👈
      <transition-group tag="ul">
        <li v-for="provider in letter" :key="provider.last_name"></li>
      </transition-group>
    </template>
  </li>
</transition-group>

демонстрация 1

Решение 2. Строковые шаблоны

Переместите шаблон в строку (используя templateoption ), что позволяет избежать ошибок парсинга DOM:

      new Vue({
  template: 
    `<transition-group tag="ul">
       <li v-for="(letter, index) in computedProviders" :key="index">
         <transition-group tag="ul">
           <li v-for="provider in letter" :key="provider.last_name"></li>
         </transition-group>
       </li>
     </transition-group>`
  //...
}).$mount('#providers')

демонстрация 2

На самом деле не знаю, что вызывает ошибку, но попробуйте создать новый компонент, который принимает letter как опора и содержит вашу внутреннюю <transition-group>. Затем вставьте этот новый компонент в свой корень v-for.

Должно получиться что-то вроде этого:

      <transition-group @before-enter="beforeEnter" @enter="enter" @leave="leave" tag="ul" v-if="computedProviders">
  <li v-for="(letter, index) in computedProviders" :key="index">
    <div>
      <p>{{index.toUpperCase()}}</p>
    </div>
    <my-component :letter="letter" />
  </li>
</transition-group>
Другие вопросы по тегам