幻灯片反向过渡,Vue Js

时间:2017-09-10 18:39:03

标签: css vue.js css-transitions vue-router

我正在使用Vue.JS开发单页面应用程序/移动应用程序。我想在更改页面时获得幻灯片效果,我可以这样做:

transition name="slide"
 router-view transition
transition

但是当用户返回页面时,我想要幻灯片的反向效果。换句话说,当用户打开新页面时,页面将来自右侧,但当他们返回时,页面将来自左侧。

Vue路由器有一个名为vue-router-transition的插件,但它不起作用。它已经过时了,它只适用于Vue的旧版本。

还有一个tutorial on dynamic transitions,但只有当它是父母路线时才有效,例如:example.com/rota1/rota2/rota3,这不是我的情况。

我在before.each.router中考虑了以下逻辑,根据用户是否点击了返回按钮设置了转换类(slide-leftslide-right)。

问题是我不知道如何在代码中应用这个逻辑。我必须将main.js中变量的值传递给app.vue,我不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

前段时间我在meta中使用了vue-router对象并添加了“假”深度,因为我没有任何子对象。如果您使用儿童,请使用此示例:https://github.com/vuejs/vue-router/blob/dev/examples/transitions/app.js

export default () => {
  return [{
      meta: {
        depth: 0
      },
      path: '/home',
      component: Home
    },
    {
      meta: {
        depth: 1
      },
      path: '/about',
      component: About
    }]
}

现在,您可以在App.vue

中自行查看
watch: {
  $route(to, from) {
    const toDepth = to.meta.depth || 0;
    const fromDepth = from.meta.depth || 0;

    this.transitionName = toDepth >= fromDepth ? 'slide-left' : 'slide-right';
  }
}

答案 1 :(得分:1)

我看到两个选项:

  1. 将变量存储在Vuex" transitionBack"并将其设置为true。将路由器链接更改为@click方法。在该方法中,首先保存变量,然后导航到链接。检查beforeRouteUpdate(to, from, next)方法上的变量。
  2. beforeRouteUpdate(to, from, next)方法中实施一些逻辑,检查链接的名称(例如,如果您只能从某个页面返回"然后保留所有这些的列表页面类型)

答案 2 :(得分:0)

希望这会有所帮助:

new Vue({
  el: '#demo',
  data: {
    slideTransition: 'slide-left',
    showChild: false,
  },
  watch: {
    showChild(value) {
      if (value) {
        this.setSlideTransition('slide-right');
      } else {
        this.setSlideTransition('slide-left');
      }
    },
  },
  methods: {
    setSlideTransition(slideDirection) {
      // Note: 300ms mentioned below is matching with css transition timing
      setTimeout(() => { this.slideTransition = slideDirection; }, 300);
    },
  },
});
body {
  margin: 0;
  color: #bdbdbd;
  background-color: #161616;
  font-family: Helvetica neue, roboto;
}

.container {
  width: 500px;
  background: #161616;
}

main {
  width: 60%;
  height: 300px;
  background-color: #333;
}

aside {
  width: 40%;
  background-color: #555;
}

.container, main, .parent, .child, .content {
  display: flex;
  align-items: center;
  justify-content: center;
}

.parent {
  background-color: deepskyblue;
}

.child {
  background-color: deeppink;
}

.container, main, aside {
  position: relative;
  height: 199px;
}

.pin {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  position: absolute;
}

.pt-50 {
  padding-top: 50px;
}

/* transitions */
.fade-enter-active,
.fade-leave-active {
  transition-property: opacity;
  transition-duration: 0.25s;
}

.fade-enter-active {
  transition-delay: 0.25s;
}

.fade-enter,
.fade-leave-active {
  opacity: 0;
}

.slide-left-leave-active,
.slide-left-enter-active,
.slide-right-leave-active,
.slide-right-enter-active {
  transition: 0.3s;
}

.slide-left-enter {
  transform: translate(100%, 0);
}

.slide-left-leave-to {
  transform: translate(-100%, 0);
}

.slide-right-enter {
  transform: translate(-100%, 0);
}

.slide-right-leave-to {
  transform: translate(100%, 0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="demo" class="container">
  <aside>
    <transition name="fade">
      <div class="pin parent" v-if="!showChild">
        <div>
          <h1>Parent</h1>
          <a href="#" @click="showChild = true">Go To Child</a>
        </div>
      </div>
    </transition>
    <transition :name="slideTransition">
      <div class="pin child" v-if="showChild">
        <div>
          <h1>Child</h1>
          <a href="#" @click="showChild = false">Go To Parent</a>
        </div>
      </div>
    </transition>        
  </aside>
  <main>
   <div>
    <h1>Main</h1>
    <transition name="fade">
      <div v-if="showChild" class="pin content pt-50" key="child">
        <h4>Child Content here</h4>
      </div>
      <div v-else="" class="pin content pt-50" key="parent">
        <h4>Parent Content here</h4>
      </div>
    </transition>
   </div>
  </main>
</div>