Vue.jsの異なるルータービュー間でアニメーションを実行することはできません

リャン

まとめVueの2つの異なるルータービューにまたがるアニメーションを作成するためのソリューションを探しています。私が遭遇した問題は、ブラウザが別のルータービューに変わると、ページが再レンダリングされることです。そのため、ブラウザが再レンダリングするとアニメーションは消えます。

アニメーション
基本的に、アプリにはホームページアバウトページの2つの異なるページがありますユーザーが青いメニューボタンをクリックすると、画面全体が表示されるまで、緑のナビゲーションメニューが左から右にスライドします。このメニューには、abouthomeの2つのリンクがありますユーザーが「」をクリックすると、白いオーバーレイが左から移動して画面全体を覆い、次に右に移動して消えます。アバウトページは消えた後に表示されます。これは、私が達成したいアニメーション効果を実証するコーデックの例です(このデモではルーターを使用していません)。https://codepen.io/wl1664209734/pen/qBamXEL
以下は、codepenのvueテンプレートでアニメーションを再作成するためのコードです。

  <template>
  <div class="wrap">
    <!--Transition Overlay -->
    <transition
      name="page-shift"
      enter-active-class="animate__animated animate__slideInLeft animate__faster"
      leave-active-class="animate__animated animate__slideOutRight animate__faster"
    >
      <div v-if="showOverlay" class="overlay"></div>
    </transition>

    <!--Navigation Menu -->
    <transition
      name="slide"
      enter-active-class="animate__animated animate__slideInLeft animate__faster"
      leave-active-class="animate__animated animate__slideOutLeft animate__faster"
    >
      <div v-if="menuOpen" class="navigation">
        <div
          class="container h-100 d-flex justify-content-center align-items-center"
        >
          <div class="text-center">
            <h3 class="font-weight-bold text-light" @click="pageShiftToHome">
              HOME
            </h3>
            <h3 class="font-weight-bold text-light" @click="pageShiftToAbout">
              ABOUT
            </h3>
          </div>
        </div>
      </div>
    </transition>

    <!--NavBar -->
    <div class="navbar d-flex justify-content-end">
      <div
        @click="menuOpen = !menuOpen"
        class="nav-link font-weight-bold mt-3 btn btn-primary"
      >
        Menu
      </div>
    </div>

    <!--Home Page -->
    <div
      v-if="showHomePage"
      class="homepage d-flex justify-content-center align-items-center"
    >
      <h1 class="text-light">HOME</h1>
    </div>

    <!--About Page -->
    <div
      v-if="showAboutPage"
      class="aboutpage d-flex justify-content-center align-items-center"
    >
      <h1 class="text-light">ABOUT</h1>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      menuOpen: false,
      showHomePage: true,
      showAboutPage: false,
      showOverlay: false
    };
  },
  methods: {
    pageShiftToHome: function () {
      this.showOverlay = !this.showOverlay;

      const _this = this;
      setTimeout(function () {
        _this.menuOpen = !_this.menuOpen;
        _this.showAboutPage = false;
        _this.showHomePage = true;
      }, 500);
      setTimeout(function () {
        _this.showOverlay = !_this.showOverlay;
      }, 1000);
    },

    pageShiftToAbout: function () {
      this.showOverlay = !this.showOverlay;

      const _this = this;
      setTimeout(function () {
        _this.menuOpen = !_this.menuOpen;
        _this.showHomePage = false;
        _this.showAboutPage = true;
      }, 500);
      setTimeout(function () {
        _this.showOverlay = !_this.showOverlay;
      }, 1000);
    }
  }
};
</script>

<!-- Use preprocessors via the lang attribute! e.g. <style lang="scss"> -->
<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  background: #292929;
}

.wrap {
  width: 100%;
  height: 100vh;
  background: #292929;

  .overlay {
    width: inherit;
    height: inherit;
    background: #fff;
    position: absolute;
    z-index: 999;
  }

  .navigation {
    width: inherit;
    height: inherit;
    background: #3ecc28;
    position: absolute;
    z-index: 111;

    h3 {
      cursor: pointer;
    }
  }

  .navbar {
    width: 100%;
    z-index: 333;
    .nav-link {
      color: #fff;
      cursor: pointer;
      border: 0;
    }
  }

  .homepage {
    width: inherit;
    height: inherit;
    position: absolute;
    top: 0;
    left: 0;
  }

  .aboutpage {
    @extend .homepage;
  }
}
</style>

私のコードの説明
ここにcodeSandboxリンクがあります、私はこのサンドボックスで問題を再現します、これは人々が私の問題をよりよく理解するのを助けると思います。https://codesandbox.io/s/vue-page-shift-anime-yp1yf
このサンドボックスでは、vueテンプレートを使用しました。これにはApp.vueという1つの主要コンポーネント、Homepage.vue、Aboutpage.vue、Background.vue、Navbar.vue、Navigation.vueという5つの他のコンポーネントが含まれています背景には含まれていナビゲーションバーナビゲーションをアプリのための静的な要素を形成します。両方のホームページAboutpageを有する背景とユニークなヘッダ。ホームページのヘッダーはHOMEで、AboutpageのヘッダーはABOUTです。次に、main.jsでルーターを構成し、App.vueにrouter-viewタグを配置します。また、Navigation.vueにrouter-linkを追加しますクリックイベント(ページシフト)をルーターリンクに追加すると、このイベントはBackground.vueに発行されます。したがって、ユーザーがリンクをクリックすると、Background.vueのpageShiftメソッドが呼び出され、アニメーションが発生します。

アプリの構造

重要なコンポーネントのコードは次のとおりです

* Main.js

import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import "bootstrap/dist/css/bootstrap.css";
import "animate.css";

import Homepage from "./components/Homepage";
import Aboutpage from "./components/Aboutpage";

Vue.use(VueRouter);
Vue.config.productionTip = false;

const router = new VueRouter({
  routes: [
    {
      path: "*",
      component: Homepage
    },
    {
      path: "/about",
      component: Aboutpage
    }
  ]
});

new Vue({
  render: (h) => h(App),
  router
}).$mount("#app");

*アプリを見る

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

<style>
body {
  background: #292929;
}

#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
</style>

* Background.vue

<template>
  <div class="wrap">
    <transition
      name="page-shift"
      enter-active-class="animate__animated animate__slideInLeft animate__faster"
      leave-active-class="animate__animated animate__slideOutRight animate__faster"
    >
      <div v-if="showOverlay" class="overlay"></div>
    </transition>
    <navigation :menuOpen="menuOpen" @page-shift="pageShift" />
    <navbar @open-menu="menuOpen = !menuOpen" />
    <div>
      <div class="page d-flex justify-content-center align-items-center">
        <h1 class="text-light">{{ header }}</h1>
      </div>
    </div>
  </div>
</template>

<script>
import Navbar from "./Navbar";
import Navigation from "./Navigation";

export default {
  name: "background",
  props: ["header"],
  data: function () {
    return {
      menuOpen: false,
      showOverlay: false,
    };
  },
  components: {
    Navbar,
    Navigation,
  },
  methods: {
    pageShift: function () {
      this.showOverlay = !this.showOverlay;
      const _this = this;
      setTimeout(function () {
        _this.menuOpen = !_this.menuOpen;
      }, 500);
      setTimeout(function () {
        _this.showOverlay = !_this.showOverlay;
      }, 1000);
    },
  },
};
</script>

<style lang="scss" scoped>
.wrap {
  width: 100%;
  height: 100vh;

  .overlay {
    width: inherit;
    height: inherit;
    background: #fff;
    position: absolute;
    z-index: 999;
  }

  .page {
    width: 100%;
    height: 100vh;
    position: absolute;
    top: 0;
    left: 0;
  }
}
</style>

*Navbar.vue

<template>
  <div class="navbar d-flex justify-content-end">
    <div
      @click="$emit('open-menu')"
      class="nav-link font-weight-bold mt-3 btn btn-primary"
    >
      Menu
    </div>
  </div>
</template>

<script>
export default {
  name: "navbar",
};
</script>

<style lang="scss">
.navbar {
  width: 100%;
  z-index: 333;
  .nav-link {
    color: #fff;
    cursor: pointer;
    border: 0;
  }
}
</style>

* Navigation.view

<template>
  <transition
    name="slide"
    enter-active-class="animate__animated animate__slideInLeft animate__faster"
    leave-active-class="animate__animated animate__slideOutLeft animate__faster"
  >
    <div v-if="menuOpen" class="navigation">
      <div
        class="container h-100 d-flex justify-content-center align-items-center"
      >
        <div class="text-center">
          <router-link to="/*" class="font-weight-bold text-light"
            ><h3 @click="$emit('page-shift')">HOME</h3></router-link
          >
          <router-link to="/about" class="font-weight-bold text-light"
            ><h3 @click="$emit('page-shift')">ABOUT</h3></router-link
          >
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  name: "navigation",
  props: ["menuOpen"],
};
</script>

<style lang="scss" scoped>
.navigation {
  width: 100%;
  height: 100%;
  background: #3ecc28;
  position: absolute;
  z-index: 111;
  top: 0;
  left: 0;

  a:hover {
    text-decoration: none;
  }

  span {
    cursor: pointer;
  }
}
</style>

* Homepage.vue

<template>
  <background :header="'HOME'" />
</template>

<script>
import Background from "./Background";

export default {
  name: "homepage",
  data: function () {
    return {
      menuOpen: false,
    };
  },
  components: {
    Background,
  },
};
</script>

<style lang="scss" scoped>
</style>

Aboutpage.vue

<template>
  <background :header="'ABOUT'" />
</template>

<script>
import Background from "./Background";

export default {
  name: "aboutpage",
  data: function () {
    return {
      menuOpen: false,
    };
  },
  components: {
    Background,
  },
};
</script>

<style lang="scss" scoped>
</style>

私が発見した問題は、同じルータービューにとどまると、アニメーションが発生することです。別のビューに移動すると、ページが再レンダリングされてすべてがリロードされるため、アニメーションはまったく発生しません。たとえば、サンドボックスで、現在家にいて、家をクリックすると、アニメーションが表示されます。ただし、ホームから約に切り替えると、ページが再読み込みされ、アニメーションが失敗します。

私が試したことは、Vueは初めてです。解決策の1つは、異なるビューを切り替えるときにページがレンダリングされないようにすることだと思います。私はそれを達成する方法がわかりません。App.vueのrouter-viewタグの周りにtransitionタグを使用しようとしましたが、理想的なアニメーションが得られません。私もキープアライブを試しましたが、まったく機能しません。私の説明が理にかなっていることを願っています、そして私はあなたの解決策を楽しみにしています!ありがとう!

問題は、を介してビュー内にナビゲーションを含めていることですBackground.vueそうしないでください。に含めますApp.vue

ルートが変更されると、<router-view />のコンテンツには、そのルートのコンポーネントの新しいインスタンスが入力されます((または)のroutes配列で設定されます)。したがって、代わりに:router/index.ts.js

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

...あなたApp.vueは含むべきです

<template>
  <div id="app">
    <navigation />
    <router-view />
  </div>
</template>

ページが変更されたときに再レンダリングしたくないページの他の部分(サイドバー、フッターなど)がある場合は、それらも中に含めますApp.vueしたがって、フッターとサイドバーを使用すると、次のようになります。

<template>
  <div id="app">
    <header>
      <navigation />
    </header>
    <main>
      <sidebar />
      <router-view />
    </main>
    <footer />
  </div>
</template>

ルートが変更<router-view />されると、再レンダリングされるだけで、ルートに設定されたアニメーションがそれに応じて実行されます。直接配置された他のレイアウト要素はApp.vue再レンダリングされません。明らかに、現在のルートに基づいてコンテンツを動的に変更すると、それらのパーツは更新されますが、ベースのDOM要素は同じままです。

暗黙的に、に<navigation />直接配置することを決定した他のものと一緒に、ビューから削除する必要がありますApp.vue

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Vue.js:JS-アニメーション-GSAPとのフック-アニメーションを機能させないままにする

分類Dev

Vue-JSでユーザーグループごとに異なるメニューを表示するための最良の方法は何ですか?

分類Dev

vue.jsのコールバックメソッドでコンポーネント変数を変更することはできません

分類Dev

Vue JsでJestテストを実行すると、「SyntaxError:モジュールの外部でインポートステートメントを使用できません」

分類Dev

vue.jsアプリケーションでビューポートメタタグを設定します

分類Dev

vue.jsで値を更新するときにCSSアニメーションを追加するにはどうすればよいですか?

分類Dev

vue.jsで値を更新するときにCSSアニメーションを追加するにはどうすればよいですか?

分類Dev

Vueトランジションは、再利用可能なコンポーネントを備えたルータービューでは機能しません

分類Dev

vue.jsフィルターは、ネストされたメソッドが実行できないことを実行しますか?

分類Dev

Vue.jsのモデルからメソッドにデータを渡すことができません

分類Dev

Djangoアプリのjsファイル内でvue.jsをインポートしようとすると、「Uncaught SyntaxError:モジュール外でimportステートメントを使用できません」

分類Dev

Vue.jsルータービューコンポーネント間でイベントを発行するにはどうすればよいですか?

分類Dev

APIデータをフェッチしてvuexで保存することはできません--vue.js

分類Dev

vue.js-大きな単一ページアプリケーションを複数のビューで整理する

分類Dev

Vue:App.vueのヘッダーナビゲーションですが、異なるビューで変更されていますか?

分類Dev

vue.jsの `v-for`でデータを並べ替えることができません(データは反復できません)

分類Dev

vue.jsの `v-for`でデータを並べ替えることができません(データは反復できません)

分類Dev

Vue.jsはconsole.logのデータを見ることができません

分類Dev

Vue.jsアプリケーションはGitlabページでは実行されません

分類Dev

スコープ付きスタイルのVueコンポーネントでCSSキーフレームアニメーションが壊れているのはなぜですか?

分類Dev

Vue.js 2.5のアップグレード後、Vue.js + TypeScript + RequireJSスタックを機能させることができません

分類Dev

Vue:テンプレートにキーを設定することはできませんが、テンプレートをdivに置き換えることはできません-ラッパーdiv要素のないv-for、ネストされたv-forループが必要です

分類Dev

Vue:テンプレートにキーを設定することはできませんが、テンプレートをdivに置き換えることはできません-ラッパーdiv要素のないv-for、ネストされたv-forループが必要です

分類Dev

@keyframesアニメーションがVue.jsで機能しないのはなぜですか?

分類Dev

Vue.jsでリストの並べ替えをアニメーション化する方法

分類Dev

Vue.js-アプリがnpmrunserveで実行されているときにターミナルを使用する

分類Dev

配列アイテムを置き換えたり、作成および削除したりする場合に、Vueのアニメーションが異なるのはなぜですか?

分類Dev

Vuexを使用してVueでmapStateを使用してデータを取得することはできません

分類Dev

vue.jsとvueルーターを使用して現在のルートの子のサブメニューを実装する方法

Related 関連記事

  1. 1

    Vue.js:JS-アニメーション-GSAPとのフック-アニメーションを機能させないままにする

  2. 2

    Vue-JSでユーザーグループごとに異なるメニューを表示するための最良の方法は何ですか?

  3. 3

    vue.jsのコールバックメソッドでコンポーネント変数を変更することはできません

  4. 4

    Vue JsでJestテストを実行すると、「SyntaxError:モジュールの外部でインポートステートメントを使用できません」

  5. 5

    vue.jsアプリケーションでビューポートメタタグを設定します

  6. 6

    vue.jsで値を更新するときにCSSアニメーションを追加するにはどうすればよいですか?

  7. 7

    vue.jsで値を更新するときにCSSアニメーションを追加するにはどうすればよいですか?

  8. 8

    Vueトランジションは、再利用可能なコンポーネントを備えたルータービューでは機能しません

  9. 9

    vue.jsフィルターは、ネストされたメソッドが実行できないことを実行しますか?

  10. 10

    Vue.jsのモデルからメソッドにデータを渡すことができません

  11. 11

    Djangoアプリのjsファイル内でvue.jsをインポートしようとすると、「Uncaught SyntaxError:モジュール外でimportステートメントを使用できません」

  12. 12

    Vue.jsルータービューコンポーネント間でイベントを発行するにはどうすればよいですか?

  13. 13

    APIデータをフェッチしてvuexで保存することはできません--vue.js

  14. 14

    vue.js-大きな単一ページアプリケーションを複数のビューで整理する

  15. 15

    Vue:App.vueのヘッダーナビゲーションですが、異なるビューで変更されていますか?

  16. 16

    vue.jsの `v-for`でデータを並べ替えることができません(データは反復できません)

  17. 17

    vue.jsの `v-for`でデータを並べ替えることができません(データは反復できません)

  18. 18

    Vue.jsはconsole.logのデータを見ることができません

  19. 19

    Vue.jsアプリケーションはGitlabページでは実行されません

  20. 20

    スコープ付きスタイルのVueコンポーネントでCSSキーフレームアニメーションが壊れているのはなぜですか?

  21. 21

    Vue.js 2.5のアップグレード後、Vue.js + TypeScript + RequireJSスタックを機能させることができません

  22. 22

    Vue:テンプレートにキーを設定することはできませんが、テンプレートをdivに置き換えることはできません-ラッパーdiv要素のないv-for、ネストされたv-forループが必要です

  23. 23

    Vue:テンプレートにキーを設定することはできませんが、テンプレートをdivに置き換えることはできません-ラッパーdiv要素のないv-for、ネストされたv-forループが必要です

  24. 24

    @keyframesアニメーションがVue.jsで機能しないのはなぜですか?

  25. 25

    Vue.jsでリストの並べ替えをアニメーション化する方法

  26. 26

    Vue.js-アプリがnpmrunserveで実行されているときにターミナルを使用する

  27. 27

    配列アイテムを置き換えたり、作成および削除したりする場合に、Vueのアニメーションが異なるのはなぜですか?

  28. 28

    Vuexを使用してVueでmapStateを使用してデータを取得することはできません

  29. 29

    vue.jsとvueルーターを使用して現在のルートの子のサブメニューを実装する方法

ホットタグ

アーカイブ