vue怎么给路由切换时添加动画

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue怎么给路由切换时添加动画相关的知识,希望对你有一定的参考价值。

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加 entering/leaving 过渡

    条件渲染 (使用 v-if)

    条件展示 (使用 v-show)

    动态组件

    组件根节点

    这里是一个典型的例子:

    <div id="demo">
    <button v-on:click="show = !show">
    Toggle
    </button>
    <transition name="fade">
    <p v-if="show">hello</p>
    </transition>
    </div>

    new Vue(
    el: '#demo',
    data:
    show: true

    )

    .fade-enter-active, .fade-leave-active
    transition: opacity .5s

    .fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */
    opacity: 0

    Toggle

    hello

    当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:

    自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。

    如果过渡组件提供了 javascript 钩子函数,这些钩子函数将在恰当的时机被调用。

    如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

    过渡的类名

    在进入/离开的过渡中,会有 6 个 class 切换。

    v-enter:定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。

    v-enter-active:定义过渡的状态。在元素整个过渡过程中作用,在元素被插入时生效,在 transition/animation 完成之后移除。这个类可以被用来定义过渡的过程时间,延迟和曲线函数。

    v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入一帧后生效 (于此同时 v-enter 被删除),在 transition/animation 完成之后移除。

    v-leave: 定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除。

    v-leave-active:定义过渡的状态。在元素整个过渡过程中作用,在离开过渡被触发后立即生效,在 transition/animation 完成之后移除。这个类可以被用来定义过渡的过程时间,延迟和曲线函数。

    v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发一帧后生效 (于此同时 v-leave 被删除),在 transition/animation 完成之后移除。

参考技术A 1、setInterval事件和组件的生命周期没有直接关系。
2、setInterval会返回一个ID 值。setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。

Vue js引导程序在折叠时添加动画

【中文标题】Vue js引导程序在折叠时添加动画【英文标题】:Vue js bootstrap add animation while collapse 【发布时间】:2018-09-10 08:28:24 【问题描述】:

我正在制作带有折叠显示/隐藏的侧边栏菜单。使用我当前的 css,崩溃并不顺利,看起来力量十足或看起来有些奇怪。

我想要在项目关闭时平滑过渡的幻灯片。但在我的情况下,发生的是当某个项目已经打开并且单击下一个项目(打开)时。那里看起来切换是强制的,并且列表的折叠似乎并不顺利。

有什么更好的方法,请提出一些更好的方法。

Fiddle Implementation.

我不知道我的方法是正确的还是我在这里遗漏了什么?

new Vue(
  el: '#app',
  methods: 
    setActiveItemId(itemIndex) 
      if (itemIndex === this.activeItemId) 
        this.activeItemId = ''
        return
      
      this.activeItemId = itemIndex
    
  ,
  data() 
    return 
      message: 'Hello Vue.js!',
      activeItemId: '',
      sideBar: [
          name: "Dashboard",
          url: "/dashboard",
          icon: "ti-world",
          children: [
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            ,
            
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            
          ]
        ,
        
          name: "Components",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            ,
            
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            
          ]
        ,
        
          name: "Validation",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            ,
            
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            
          ]
        
      ]
    
  ,
  computed: 
    isActive() 
      return this.activeItemId !== ''
    
  
)
.collapse.show 
  display: block;


.collapse 
  display: none;


.list-unstyled 
  padding-left: 0;
  list-style: none;


.collapse.list-unstyled 
  padding-left: 15px;


nav.side-navbar 
  background: #fff;
  min-width: 250px;
  max-width: 250px;
  color: #000;
  -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  z-index: 999;


nav.side-navbar ul a:hover 
  background: orange;
  color: #fff !important;


nav.side-navbar ul a 
  padding: 10px 15px;
  text-decoration: none;
  display: block;
  font-weight: 300;
  border-left: 4px solid transparent;
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <nav class="side-navbar">
    <ul class="list-unstyled">
      <li>
        <a>
          <i class="ti-home"></i>Home</a>
      </li>
      <li v-for="(x, itemIndex) in sideBar" :key="itemIndex">
        <a @click="setActiveItemId(itemIndex)">
          <i class="fa" :class="x.icon"></i>x.name
        </a>
        <ul :id="x.id" class="collapse list-unstyled" :class="'show':activeItemId === itemIndex  && isActive">
          <li v-for="y in x.children" :key="y.id">
            <a>y.name</a>
          </li>
        </ul>
      </li>
    </ul>
  </nav>
</div>

【问题讨论】:

当你说“不流畅”是什么意思?它看起来还可以,但缺少任何类型的动画。您的代码中没有任何内容暗示将要发生转换,因此您似乎没有尝试过任何事情。如果你想要动画,那会是什么类型的?幻灯片?褪色?除非您的问题很明确,否则我们无法猜测或提出任何建议。 关闭项目时平滑过渡的幻灯片。但在我的情况下,发生的事情是某个项目已经打开并且单击了下一个项目。在那里,切换似乎正在被强制执行,并且列表的折叠似乎并不顺畅。 【参考方案1】:

您可以使用Vue's List Transitions&lt;transition-group&gt; 标签)。

将子列表ul更改为:

<ul :id="x.id" class="collapse list-unstyled show">
  <transition-group name="list">
    <li v-for="y in (activeItemId === itemIndex  && isActive ? x.children : [])" :key="y.name">
      <a>y.name</a>
    </li>
  </transition-group>
</ul>

主要不是隐藏&lt;ul&gt;,而是将v-for 数组更改为空/从空。请注意,我还更改了 il 的键,因为您使用了无效的道具。

并为过渡添加以下 CSS:

.list-enter 
  opacity: 0;

.list-enter-active 
  animation: slide-in .5s ease-out forwards;

.list-leave-to, .list-leave-active 
  opacity: 0;
  animation: slide-out .5s ease-out forwards;

@keyframes slide-in 
  from  height: 0;  to  height: 40px; 

@keyframes slide-out 
  from  height: 40px;  to  height: 0; 

更新JSFiddle here。演示如下。

new Vue(
  el: '#app',
  methods: 
    setActiveItemId(itemIndex) 
      if (itemIndex === this.activeItemId) 
        this.activeItemId = ''
        return
      
      this.activeItemId = itemIndex
    
  ,
  data() 
    return 
      message: 'Hello Vue.js!',
      activeItemId: '',
      sideBar: [
          name: "Dashboard",
          url: "/dashboard",
          icon: "ti-world",
          children: [
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            ,
            
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            
          ]
        ,
        
          name: "Components",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            ,
            
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            
          ]
        ,
        
          name: "Validation",
          url: "/components",
          icon: "ti-pencil-alt",
          children: [
              name: "Buttons",
              url: "/components/buttons",
              icon: "fa-book",
            ,
            
              name: "Social Buttons",
              url: "/components/social-buttons",
              icon: "icon-puzzle",
            
          ]
        
      ]
    
  ,
  computed: 
    isActive() 
      return this.activeItemId !== ''
    
  
)
.collapse.show 
  display: block;


.collapse 
  display: none;


.list-unstyled 
  padding-left: 0;
  list-style: none;


.collapse.list-unstyled 
  padding-left: 15px;


nav.side-navbar 
  background: #fff;
  min-width: 250px;
  max-width: 250px;
  color: #000;
  -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
  z-index: 999;


nav.side-navbar ul a:hover 
  background: orange;
  color: #fff !important;


nav.side-navbar ul a 
  padding: 10px 15px;
  text-decoration: none;
  display: block;
  font-weight: 300;
  border-left: 4px solid transparent;


.list-enter 
  opacity: 0;

.list-enter-active 
  animation: slide-in .5s ease-out forwards;

.list-leave-to, .list-leave-active 
  opacity: 0;
  animation: slide-out .5s ease-out forwards;

@keyframes slide-in 
  from  height: 0;  to  height: 40px; 

@keyframes slide-out 
  from  height: 40px;  to  height: 0; 
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <nav class="side-navbar">
    <ul class="list-unstyled">
      <li>
        <a>
          <i class="ti-home"></i>Home</a>
      </li>
      <li v-for="(x, itemIndex) in sideBar" :key="itemIndex">
        <a @click="setActiveItemId(itemIndex)">
          <i class="fa" :class="x.icon"></i>x.name
        </a>
        <ul :id="x.id" class="collapse list-unstyled show">
          <transition-group name="list">
            <li v-for="y in (activeItemId === itemIndex  && isActive ? x.children : [])" :key="y.name">
              <a>y.name</a>
            </li>
          </transition-group>
        </ul>
      </li>
    </ul>
  </nav>
</div>

【讨论】:

【参考方案2】:

有更简单的解决方案,尝试将这段 css 添加到您的样式中。

.show 
  transition: width 0.5s, height 0.5s, transform 0.5s;


【讨论】:

以上是关于vue怎么给路由切换时添加动画的主要内容,如果未能解决你的问题,请参考以下文章

Vue-router结合transition实现app前进后退动画切换效果

vue组件路由事件

基于vux的Vue路由切换动画

vuex实现路由切换动画同时嵌套路由同样使用

vue 子路由切换出现闪烁的问题。

如何在 Vue js 中创建一个组件以永远不会删除我添加到其中的数据?当我切换路由时,组件会删除它获得的所有数据