如何在 v-for 循环中实现 <transition-group>?

How to implement <transition-group> inside a v-for loop?

对此有一个建议的答案,但该解决方案对我不起作用。我有一个嵌套的 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 is not defined.

我尝试按照 here 的建议添加 :letter="letter",但它仍然不适合我。有什么建议么?如果有更好的方法,我很乐意重新格式化代码。

编辑:为了回应这里的一些评论,首先,我将 Vue 注入到基于 PHP 的 Wordpress 模板中,因此我无法创建单独的组件。我不知道这是否是导致问题的部分原因,或者为什么你们中的一些人可以 运行 没有错误的代码。

这是迭代的 JSON 示例:

{
   a: [
       {
        first_name: 'John',
        last_name: 'Apple',
        suffix: 'DDS',
        permalink: 'www.test.com',
        thumbnail: '<img src="test.com" />',
        specialty: 'Some specialty'
       }, 
       {
        first_name: 'Jane',
        last_name: 'Apple',
        suffix: 'DDS',
        permalink: 'www.test.com',
        thumbnail: '<img src="test.com" />',
        specialty: 'Some specialty'
       }
      ],
    d: [
       {
        first_name: 'John',
        last_name: 'Doe',
        suffix: 'DDS',
        permalink: 'www.test.com',
        thumbnail: '<img src="test.com" />',
        specialty: 'Some specialty'
       }, 
       {
        first_name: 'Jane',
        last_name: 'Doe',
        suffix: 'DDS',
        permalink: 'www.test.com',
        thumbnail: '<img src="test.com" />',
        specialty: 'Some specialty'
       }
      ]
}

真的不知道是什么导致了错误,但尝试创建一个接受 letter 作为 prop 并包含您的内部 <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>

其中一个 caveats with using in-DOM templates 是浏览器在 Vue 到达它之前解析 DOM 。浏览器不知道 <transition-group tag="ul"> 是什么,所以它会被忽略。相反,它会在另一个 <li> 中看到一个 <li>。由于 <li> 元素通常不能嵌套,因此浏览器将 <li v-for="provider in letter" :key="provider.last_name"> 提升到定义 letter.

的父元素 <li> 之外

Removing Vue and inspecting the DOM 将揭示问题:

当 Vue 处理该模板时,它遇到 letter,这在技术上未在 v-for 之外声明,导致您看到的错误。

解决方案 1:<template> 包装器

如果您需要使用 in-DOM 模板,请用 <template> 包裹内部 <transition-group> 以便浏览器将忽略它:

<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>

demo 1

解决方案 2:字符串模板

将模板移动到字符串中(使用 template option),这避免了 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')

demo 2