0. はじめに
- 「レスポンシブでイケそう、でもアプリとしては UA 分割する」ような場合有効そう
- 今回は Desktop or その他(= Mobile) で分岐させています
package | version |
---|---|
nuxt | 2.6.1 |
vue | 2.6.10 |
nuxt-device-detect | 1.1.4 |
1. User Agent を判定する
https://github.com/dotneet/nuxt-device-detect
を利用しましたが、ここはなんでも大丈夫です。
グローバルの Mixin として、こんな感じに layout を分岐させると便利です。
~/plugins/global-mixins.js
import Vue from 'vue'
Vue.mixin({
layout({ app }) {
return app.$device.isDesktop ? 'desktop' : 'mobile'
}
})
レイアウトコンポーネント
レイアウトコンポーネントがそれぞれ #desktop
or #mobile
を持っていることが重要です。
下記では 2レイアウト準備していますが、動的に出力しても問題ありません。
~/layouts/desktop.vue
<template>
<div id="desktop">
<nuxt />
</div>
</template>
~/layouts/mobile.vue
<template>
<div id="mobile">
<nuxt />
</div>
</template>
2. あとは scss でなんとかする
mixins.scss
@mixin desktop {
#desktop & {
@content;
}
}
@mixin mobile {
#mobile & {
@content;
}
}
もちろん SCSS 周りの設定もいくつか必要ですが、割愛します
参考:
3. 使用例
~/components/TheFooter.vue
<template>
<script>
<style lang="scss" scoped>
.footer {
color: red;
@include desktop {
color: green;
}
}
</style>
祖先に #desktop
や #mobile
があれば適用するモノですね。
いつかレスポンシブになるかもしれない際、mixin 内を変更すれば、メディアクエリへの移行も比較的楽に出来そうです。
Help wanted.
Desktop 時に、Mobile 時の CSS を出力しない ような方法はありませんか? 下記のように。
HogeHoge.vue
<style scoped v-if="$device.isDesktop">
.hoge {
width: 800px;
}
</style>
<style scoped v-else>
.hoge {
width: 100%;
}
</style>