【问题标题】:Vuejs transition on table rows表格行上的 Vuejs 转换
【发布时间】:2017-08-16 17:57:25
【问题描述】:

我正在尝试在 html 表格行 (vue.js) 上进行转换(动画),但没有成功。这是完整的示例

  new Vue({
    el: '#data',
    data: {
      items: [
        {
          data: 'd1',
          more: false
        },
        {
          data: 'd2',
          more: false
        },
      ]
    }

  });
.fade-enter-active, .fade-leave-active {
        transition: opacity 2s
      }
      .fade-enter, .fade-leave-to  {
        opacity: 0
      }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>


    <div class="container-fluid" id="data">
      <br>
      <br>
      <table border="1" class="table table-bordered">
        <thead class="thead-inverse">
          <tr>
            <th>anim</th>
          </tr>
        </thead>
        <tbody>  
        <template v-for="item, k in items">
          <tr>
            <td><button @click="item.more = !item.more" type="button" 
                         v-bind:class="[item.more ? 'btn-danger' : 'btn-primary']" class="btn">Show the hidden row</button></td>
          </tr>

          <transition name="fade" > 
            <tr  v-bind:key="item" v-if="item.more">
              <td><p >{{k + 1}} - {{item.data}}</p></td>
            </tr>
          </transition>

        </template>
        </tbody>
      </table>
    </div>

我期望隐藏的表格行在出现时应该在 opacity 属性上出现过渡/动画,但是什么都没有发生,我应该怎么做?这完全适用于跨度或其他元素。

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    所以,首先我想指出的是,如果您使用了字符串模板,那么您问题中的代码将按原样工作。

    console.clear()
    new Vue({
        el: '#data',
        template: `
         <div>
              <br>
          <br>
          <table border="1" class="table table-bordered">
            <thead class="thead-inverse">
              <tr>
                <th>anim</th>
              </tr>
            </thead>
            <tbody>  
            <template v-for="item, k in items">
              <tr>
                <td><button @click="item.more = !item.more" type="button" 
                             v-bind:class="[item.more ? 'btn-danger' : 'btn-primary']" class="btn">Show the hidden row</button></td>
              </tr>
    
              <transition name="fade" > 
                <tr  v-bind:key="item" v-if="item.more">
                  <td><p >{{k + 1}} - {{item.data}}</p></td>
                </tr>
              </transition>
    
            </template>
            </tbody>
          </table>
          </div>
        `,
        data: {
          items: [
            {
              data: 'd1',
              more: false
            },
            {
              data: 'd2',
              more: false
            },
          ]
        }
    
      });
    .fade-enter-active, .fade-leave-active {
            transition: opacity 2s
          }
          .fade-enter, .fade-leave-to  {
            opacity: 0
          }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
    
    
        <div class="container-fluid" id="data">
    
        </div>

    注意,在这个例子中所做的唯一变化是我将 Vue 的模板变成了一个字符串,而不是在 DOM 中定义模板。这种单一更改起作用的原因是,当您使用“in DOM”模板时,浏览器会将 HTML prior 解析为 Vue 将模板转换为渲染函数。当您使用table 元素时,浏览器对它们允许在表格中呈现哪些类型的元素非常挑剔;通常,只有与表格相关的元素(theadtbodytrtd 等)。 transition 显然不是与它相处的元素(尽管有点令人惊讶的是,它并没有被template 窒息)。

    但是,字符串模板永远不会被浏览器解析,它们会直接转换为渲染函数,因此它们将按照您编写的方式工作。所以我的第一个建议是,只需使用字符串模板

    如果您想继续使用 in DOM 模板,我们需要对代码进行一些更改。首先,我们需要将过渡移动到浏览器满意的地方。使用表格,我们可以通过将其移动到 tbody 标记并使用 Vue 的特殊 is 指令轻松地做到这一点。其次,因为我们的过渡现在将应用于多个元素,所以我们需要将其切换为transition-group

    因为我们使用transition-group 转换中的每个元素必须有一个键。因此,对于每一行,我们只需为该行添加一个键。

    console.clear()
    new Vue({
      el: '#data',
      data: {
        items: [{
            data: 'd1',
            more: false
          },
          {
            data: 'd2',
            more: false
          },
        ]
      }
    
    });
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity 2s
    }
    
    .fade-enter,
    .fade-leave-to {
      opacity: 0
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
    
    <div class="container-fluid" id="data">
      <br>
      <br>
      <table border="1" class="table table-bordered">
        <thead class="thead-inverse">
          <tr>
            <th>anim</th>
          </tr>
        </thead>
        <tbody  name="fade" is="transition-group">
          <template v-for="item, k in items">
              <tr v-bind:key="`button-${item.data}`">
                <td>
                  <button @click="item.more = !item.more" 
                          type="button" 
                          v-bind:class="[item.more ? 'btn-danger' : 'btn-primary']" 
                          class="btn">Show the hidden row
                  </button>
                </td>
              </tr>
              <tr  v-bind:key="`detail-${item.data}`" v-if="item.more">
                <td><p >{{k + 1}} - {{item.data}}</p></td>
              </tr>
            </template>
        </tbody>
      </table>
    </div>

    【讨论】:

      【解决方案2】:

      尝试完全删除 标记并改为这样做:

       <tr name="fade" is="transition" v-bind:key="item.data" v-if="item.more">
      

      来源:https://github.com/vuejs/vue/issues/3907#issuecomment-253111682

      小提琴:https://jsfiddle.net/c8vqajb4/3/

      更新:

      我们最终使用了一个转换组:

      <tbody name="fade" is="transition-group">
          <tr class="row" v-bind:key="item.data" v-if="item.more">
            <td><p >{{k + 1}} - {{item.data}}</p></td>
           </tr>
      </tbody>
      

      这里建议:https://vuejs.org/v2/guide/transitions.html#List-Transitions

      小提琴:https://jsfiddle.net/c8vqajb4/4/

      【讨论】:

      • 谢谢,但没有工作我忘了提到我已经尝试过可以通过基本谷歌搜索找到的例子,然后我在这里问(在我的例子中,@Terry 提到我正在研究单个元素请参阅使用的密钥),更准确地说,您的建议仅在关闭/隐藏阶段工作,而不是在显示中
      • 我用一个有效的小提琴更新了答案。我认为使用 item 作为 key 而不是 item.data 存在错误,因为 Vue 更喜欢使用字符串或数字而不是 object 来键入 item。
      • 有趣的是你能提供一个关于这个事实的链接吗,现在对象或字符串在显示项目阶段仍然没有工作没有区别。
      • 我在控制台收到警告:[Vue warn]: children must be keyed:
      • 我认为代码有点混乱。您可能正在寻找的是closer to this
      【解决方案3】:

      过渡仅适用于单个渲染元素

      如果我们在元素内移动过渡,它会起作用

      还应该考虑使用可能有帮助的过渡组

      【讨论】:

      • 谢谢,但我已经尝试过,但没有成功,你能提供一个例子吗
      • 我认为@mikl 将&lt;transition&gt; 用于单数元素,因此您的答案不正确。
      • 例如"

        {{k + 1}} - {{item.data} }

        ..."
      • 我看到你已经在 tr 元素中移动了过渡,这不是我想要做的
      • 也让它的工作方式与其他评论类似:
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签