web-dev-qa-db-ja.com

vue routerでボディスタイルを変更する

Vue router を2ページで使用しています:

let routes = [
    {
        path: '/',
        component: require('./components/HomeView.vue')
    },
    {
        path: '/intro',
        component: require('./components/IntroView.vue')
    }
]

これはうまく機能しますが、私のコンポーネントにはそれぞれ異なるボディスタイルがあります。

HomeView.vue:

<template>
    <p>This is the home page!</p>
</template>

<script>
    export default {

    }
</script>

<style>
    body {
        background: red;
    }
</style>

IntroView.vue:

<template>
    <div>
        <h1>Introduction</h1>
    </div>
</template>

<script>
    export default {

    }
</script>

<style>
    body {
        background: pink;
    }
</style>

私の目標は、これら2つのページに異なるバックグラウンドスタイルを持たせることです(最終的にはそれらの間で移行します)。しかし、homeルート(red背景付き)に移動して、introルートをクリックすると、背景色はredpink)に変更してほしい。

編集:index.html:

  <body>
    <div id="app">
        <router-link to="/" exact>Home</router-link>
        <router-link to="/intro">Introduction</router-link>
        <router-view></router-view>
    </div>
    <script src="/dist/build.js"></script>
  </body>
15
GluePear

lifecycle hookbeforeCreateとグローバルスタイルシートで動作するようにしました。 global.css

body.home {
    background: red;
}
body.intro {
    background: pink;
}

の中に <script>セクションのHomeView.vue

export default {
    beforeCreate: function() {
        document.body.className = 'home';
    }
}

IntroView.vue

30
GluePear

または、これを使用できます

Vue-routerを使用してページ本体クラスを制御できます。同様の問題に直面したときにこれを書いた。また、 コンポーネントがクリックされたときにボディにクラスを追加しますか? も参照します。

3
Nikolay Antonov
watch: {
  $route: {
    handler (to, from) {
      const body = document.getElementsByTagName('body')[0];
      if (from !== undefined) {
        body.classList.remove('page--' + from.name.toLowerCase());
      }
      body.classList.add('page--' + to.name.toLowerCase());
    },
    immediate: true,
  }
},

別の非常に単純なソリューションで、ベースのApp.vueファイルに追加します。 to.nameをto.meta.classまたはより具体的なものに似たものに置き換えることができます。これは一度すればいいのですが、型ソリューションは永遠に動作します。

2
Lomax

特定のルートで#appコンテナと一緒にhtmlおよびbodyタグのスタイルを変更したいときに問題に遭遇しました。 、これは非常に複雑になる可能性があります。

読んだ後:

あなたのApp.vue(集中状態と見なすことができます):

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

<script>
  export default {
    name: 'my-app',
    methods: {
      handleStyles () {
        // Red style to the body tag for the home page
        if (['/'].includes(this.$route.path)) document.body.className = 'bg-red'
        // Pink style to the body tag for all other pages
        else if (document.body.classList.contains('bg-red')) document.body.className = 'bg-pink'
      }
    },
    // Handle styles when the app is initially loaded
    mounted () {
      this.handleStyles()
    },
    // Handle styles when the route changes
    watch: {
      '$route' () {
        this.handleStyles()
      }
    }
  }
</script>

<style>
  .bg-red {
    background: red;
  }
  .bg-pink {
    background: pink;
  }
</style>

そのため、ルート/には赤のスタイルが適用され、他のすべてのルートにはピンクのスタイルが適用されます。

handleStylesロジックはbeforeCreatedフックで処理できますが、私の場合、これはhtmlおよびbodyスタイルにのみ影響しますが、#appルータービューがレンダリングされる要素は、domがマウントされている場合にのみ使用できるため、少し拡張性の高いソリューションだと思います。

1

クラスがビュー固有の場合、これが役立つかもしれません

methods: {
  toggleBodyClass(addRemoveClass, className) {
    const el = document.body;

    if (addRemoveClass === 'addClass') {
      el.classList.add(className);
    } else {
      el.classList.remove(className);
    }
  },
},
mounted() {
  this.toggleBodyClass('addClass', 'mb-0');
},
destroyed() {
  this.toggleBodyClass('removeClass', 'mb-0');
},

methodsセクションをmixinに移動すると、コードはDRYになります。

1
Syed

afterEachフックを使用して、ルーターファイルで直接行うこともできます。

mainRouter.afterEach((to) => {
    if (["dialogs", "snippets"].includes(to.name)) {
        document.body.style.backgroundColor = "#F7F7F7";
        // or document.body.classList.add(className);
    } else {
        document.body.style.backgroundColor = "#FFFFFF";
        // or document.body.classList.remove(className);
    }
});

afterEachフックドキュメント

toは、ルート名(名前が付いている場合)、パスなどを含むルートオブジェクトです。 すべての小道具のドキュメント

0
Loren

Style要素でscoped属性を使用できます。次に、スタイルはそのvueファイルにのみ制限されます。

HomeView.vue:

<template>
    <p>This is the home page!</p>
</template>

<script>
    export default {

    }
</script>

<style scoped>
    body {
        background: red;
    }
</style>

IntroView.vue:

<template>
    <div>
        <h1>Introduction</h1>
    </div>
</template>

<script>
    export default {

    }
</script>

<style scoped>
    body {
        background: pink;
    }
</style>
0
Cazci_269