代码之家  ›  专栏  ›  技术社区  ›  Jaeger

如何设置基于道具的动画转换?

  •  0
  • Jaeger  · 技术社区  · 6 年前

    所以我对Vuejs很不满意,但我有反应的经验…这没用。

    我的初始目标是使4页可用,并且,由于它们有一个“顺序”,所以转换类名将相应地更改。

    这是我的 main.js 文件

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Landing from "./components/Landing.vue";
    import Bio from "./components/Bio.vue";
    import Shop from "./components/Shop.vue";
    import Contact from "./components/Contact.vue";
    import App from "./components/App.vue";
    import "./assets/style.css";
    
    Vue.config.productionTip = false;
    Vue.use(VueRouter);
    
    const router = new VueRouter({
      mode: "history",
    
      routes: [
        {
          path: "/",
          component: Landing,
          name: "landing",
          props: { order: 1 }
        },
        {
          path: "/bio",
          component: Bio,
          name: "bio",
          props: { order: 2 }
        },
        {
          path: "/shop",
          component: Shop,
          name: "shop",
          props: { order: 3 }
        },
    
        {
          path: "/contact",
          component: Contact,
          name: "contact",
          props: { order: 4 }
        }
      ]
    });
    
    router.beforeEach((to, from, next) => {
      // TypeError: Cannot read property 'props' of undefined
      console.log(from.matched[0].props);
      next();
    });
    
    let vm = new Vue({
      router,
      el: "#app",
      data: {
        transitionName: ""
      },
      render: h => h(App)
    });
    

    这是我的 App.vue :

    <template>
      <div id="app">
        <transition name="test"> // will soon be replaced by ":name="transitionName"
          <router-view></router-view>
        </transition>
      </div>
    </template>
    
    <script>
    // I don't know what I'm doing
    export default {
      props: ["className"],
    
      data() {
        return {
          transition: this.className
        };
      }
    };
    </script>
    
    
    <style>
    .test-enter-active,
    .test-leave-active {
      transition-property: opacity;
      transition-duration: 0.25s;
    }
    
    .test-enter-active {
      transition-delay: 0.25s;
    }
    
    .test-enter,
    .test-leave-active {
      opacity: 0;
    }
    
    #Todo: Add missing classNames;
    </style>
    

    我想比较一下这两种顺序的道具,以了解选择的转换,但是,由于我对Vue很陌生,所以我正在努力正确地检索它们,或者可能我根本没做什么好事。

    根据这个链接,我不想在URL中传递道具。另外,当我控制台日志 from 来自 router.beforeEach 方法( to 好像不管用,但我听说过 nextTick() )我可以找到我的道具,但是它找不到我测试过的道具。

    我如何解决我的问题?

    提前谢谢你

    1 回复  |  直到 6 年前
        1
  •  1
  •   Daniel    6 年前

    下面是一个使用 meta 参数以确定要使用的动画

    Vue.use(VueRouter);
    
    const Home = {
      template: `
        <div class="home">
          <h2>Home</h2>
          <p>hello</p>
        </div>
      `
    };
    
    const Parent = {
      data() {
        return {
          transitionName: "slide-left",
        };
      },
      beforeRouteUpdate(to, from, next) {
        this.transitionName = to.meta.animation;
        next();
      },
      template: `
        <div class="parent">
          <h2>Parent</h2>
          {{transitionName}}
          <transition :name="transitionName">
            <router-view class="child-view"></router-view>
          </transition>
        </div>
      `
    };
    
    const Default = { template: '<div class="default">default</div>' };
    const Foo = { template: '<div class="foo">foo</div>' };
    const Bar = { template: '<div class="bar">bar</div>' };
    const routes = [
      { path: "/", component: Home, td: 3, meta: {animation: 'slide-up'}, },
      {
        path: "/parent",
        component: Parent,
        td: 1,
        meta: {animation: 'slide-down'},
        children: [
          { path: "", component: Default, meta: {animation: 'slide-down'}},
          { path: "foo", component: Foo, meta: {animation: 'slide-right'}},
          { path: "bar", component: Bar, meta: {animation: 'slide-left'}}
        ]
      }
    ]
    const router = new VueRouter({
      mode: "history",
      routes
    });
    
    new Vue({
      router,
      template: `<div id="app">
          <h1>Transitions</h1>
          <ul>
            <li><router-link to="/">/</router-link></li>
            <li><router-link to="/parent">/parent</router-link></li>
            <li><router-link to="/parent/foo">/parent/foo</router-link></li>
            <li><router-link to="/parent/bar">/parent/bar</router-link></li>
          </ul>
          <transition name="fade" mode="out-in">
            <router-view class="view"></router-view>
          </transition>
        </div>`
    }).$mount("#app");
    .fade-enter-active, .fade-leave-active {
    /*   transition-property: opacity; */
    /*   transition-timing-function: ease; */
      transition: all .5s cubic-bezier(.55,0,.1,1);
    }
    .fade-enter, .fade-leave-active {
      opacity: 0
    }
    .view {
      width: 50%;
      margin: 0 auto;
    }
    .child-view {
      position: absolute;
      display: block;
      top: 50%;
      transition: all .5s cubic-bezier(.55,0,.1,1);
    }
    .slide-left-enter, .slide-right-leave-active {
      opacity: 0;
      -webkit-transform: translate(30px, 0);
      transform: translate(30px, 0);
    }
    .slide-left-leave-active, .slide-right-enter {
      opacity: 0;
      -webkit-transform: translate(-30px, 0);
      transform: translate(-30px, 0);
    }
    .slide-up-enter, .slide-down-leave-active {
      opacity: 0;
      -webkit-transform: translate(0, 30px);
      transform: translate(0, 30px);
    }
    .slide-up-leave-active, .slide-down-enter {
      opacity: 0;
      -webkit-transform: translate(0, -30p0);
      transform: translate(0, -30px);
    }
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.3.0/vue-router.min.js"></script>
    <div id="app"></div>