【问题标题】:Vue.js animate page transitions with javascriptVue.js 使用 javascript 动画页面过渡
【发布时间】:2018-08-09 15:26:03
【问题描述】:

我有一个使用 vue-router 包的简单 vue 应用程序,其中包含 3 条路由。假设主页有 3 个大方形列,大约一个大文本块和一个包含 4 个表单行的表单。

当我在<router-view/> 元素周围使用默认的<transition/> 元素时,它会很好地淡入淡出,但我希望每条路线都有特定的动画。主页应该错开 3 个块,关于应该从顶部淡入大文本块和联系人应该错开表单字段。

我该怎么做? 我尝试使用 javascript 钩子 (https://vuejs.org/v2/guide/transitions.html#JavaScript-Hooks),但我无法让它工作。

routes.js

import home from './components/Home.vue';
import about from './components/About.vue';
import contact from './components/Contact.vue';

export default [
{ path: '/',        component: home },
{ path: '/about',   component: about },
{ path: '/contact', component: contact }
];

App.vue

<template>
    <router-view></router-view>
 </template>

<script>
export default {
  data () {
    return {
    }
  }
}
</script>

<style>
</style>

Home.js

<template>
  <transition>
    <div id="intro">
      <div class="columns">
        <div class="column">
          Column 1
        </div>
        <div class="column">
          Column 2
        </div>
        <div class="column">
          Column 3
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  data () {
    return {
    }
  },
  methods: {
    beforeEnter: function (el) {
      alert('before');
    }
  },
}
</script>

<style scoped>
</style>

我希望 beforeEnter 方法会起作用,但事实并非如此......

【问题讨论】:

    标签: javascript vue.js transition vue-router


    【解决方案1】:

    在你的组件中添加:

    beforeRouteEnter (to, from, next) {
        next(vm=>{
            vm.enter()
        })
    },
    beforeRouteLeave (to, from, next) {
        this.leave(next)
    },
    methods:{
        enter(){
            console.log('animation in')
        },
        leave(done){
            console.log('animation out, onComplete:done()')
            done()
        }
    }
    

    【讨论】:

      【解决方案2】:

      查看vue-router's transitions 的文档。文档建议您将watch 添加到&lt;transition&gt; 可见的范围内,以便您可以更改name 属性。

      例如:

      const Home = {
        name: "Home",
        template: "<div class='view'>I'm Home</div>"
      };
      
      const Foo = {
        name: "Foo",
        template: "<div class='view'>I'm Foo</div>"
      };
      
      const Bar = {
        name: "Bar",
        template: "<div class='view'>I'm Bar</div>"
      };
      
      const router = new VueRouter({
        routes: [{
          name: "Home",
          path: "/",
          component: Home
        }, {
          name: "Foo",
          path: "/foo",
          component: Foo
        }, {
          name: "Bar",
          path: "/bar",
          component: Bar
        }]
      });
      
      const app = new Vue({
        el: "#app",
        router,
        data() {
          return {
            transitionToUse: "spin"
          };
        },
        watch: {
          $route(to, from) {
            switch (to.name) {
              case "Foo":
                this.transitionToUse = "fade";
                break;
              case "Bar":
                this.transitionToUse = "spin";
                break;
              default:
                this.transitionToUse = "grow";
                break;
            }
          }
        }
      });
      main {
        text-align: center;
      }
      
      .view {
        display: inline-block;
      }
      
      
      /*fade transition*/
      
      .fade-enter-active,
      .fade-leave-active {
        transition: opacity .5s;
      }
      
      .fade-enter,
      .fade-leave-to {
        opacity: 0;
      }
      
      
      /*spin transition*/
      
      .spin-enter-active,
      .spin-leave-active {
        transition: transform .5s;
      }
      
      .spin-enter,
      .spin-leave-to {
        transform: rotate(360deg);
      }
      
      
      /*grow transition*/
      
      .grow-enter-active,
      .grow-leave-active {
        transition: transform .5s;
      }
      
      .grow-enter,
      .grow-leave-to {
        transform: scale(4);
      }
      <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>
      <script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
      <div id="app">
        <nav>
          <ul>
            <li>
              <router-link to="/">Home</router-link>
            </li>
            <li>
              <router-link to="/foo">Foo</router-link>
            </li>
            <li>
              <router-link to="/bar">Bar</router-link>
            </li>
          </ul>
        </nav>
        <main>
          <h1></h1>
          <transition :name="transitionToUse" mode="out-in">
            <router-view></router-view>
          </transition>
        </main>
      </div>

      【讨论】:

      • 我正在寻找一个 javascript 实现,没有 css 动画,因为我想在 JS 中完成关于状态和内容的控制。我想错开元素,...
      【解决方案3】:

      如果我理解你的话,你想要这样的东西:

      在您的 App.vue 中:

      <template>
        <transition :name='transitionName'>
          <router-view ></router-view>
        </transition>
      </template>
      
      <script>
      export default {
        data: () => ({
          transitionName: 'transitionHome'
        }),
        watch: {
          '$route' (to, from) {
            const contact = to.path === '/contact' ? true : false
            const home =  to.path === '/' ? true : false
            const about =  to.path === '/about' ? true : false
            if (contact === true) {
              this.transitionName = 'transitionContact'
            } else if (about === true) {
              this.transitionName = 'transitionAbout'
            } else {
              this.transitionName = 'transitionHome'
            }
          }
        }
      }
      </script>
      

      好吧,也许这不是最好的解决方案。

      【讨论】:

      • 这也适用于 css 动画,我正在寻找用 javascript 控制动画..
      • @frederikvdbe 你找到解决方案了吗?
      • @besrabasant 我改用了 nuxt.js,nuxt 很棒!
      猜你喜欢
      • 1970-01-01
      • 2015-12-11
      • 2018-02-28
      • 2017-06-02
      • 1970-01-01
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 2017-10-29
      相关资源
      最近更新 更多