Vue.js:ダウンロードボタンを、環境に応じて出し分けよう【プログラミングクッキング】

アプリのダウンロード画面などで、アクセスしてきた環境に合わせてダウンロードボタンが、変化するページが良くあります。

ブラウザーが持っている「ユーザーエージェント」情報を使えば簡単に実装できます。Vue.jsで作ってみましょう。

HTMLを入手しよう

今回、ベースとなる HTMLは Start Bootstrapで配布されている MITライセンスのテンプレートを利用します。

こちらの、Stylish Portfolioをダウンロードしましょう。

ボタンを増やそう

そしたら、62行目付近にある以下のコードをコピーペーストしてボタンを増やします。

<a class="btn btn-primary btn-xl js-scroll-trigger" href="#about">Find Out More</a>

そして、「btn-primary」を「btn-dark」に変えておきます。

<a class="btn btn-primary btn-xl js-scroll-trigger" href="#about">Windows版</a>
<a class="btn btn-dark btn-xl js-scroll-trigger" href="#about">macOS版</a>

このボタンを出し分けていきましょう。

Vue.jsを組み込もう

続いて、Vue.jsを組み込みます。以下のように開発版のコードをコピーして、ファイルの最後に貼り付けましょう。

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

そして、Vue.jsが対象とすると要素を決めるため、<header>タグに、id属性を付加して、

<header id="app" ...>

Vue.jsでこれを指定します。

<script>
var app = new Vue({
  el: "#app",
})
</script>

v-ifを使って表示・非表示を制御しよう

Vue.jsで要素を表示・非表示するには「v-if」という構文を使います。まずは例えば、次のようにdataを定義しましょう。

<script>
var app = new Vue({
  el: "#app",
  data: {
    value: true
  }
})
</script>

そして、ボタンのHTMLで、ここで定義した「value」を使って、v-ifを定義します。

<a v-if="value" ...>Windows版</a>

すると、「value」がtrueの時は表示され、falseの時は非表示になります。

ユーザーエージェントを取得しよう

アクセスしてきた環境が、Windowsなのか macOSなのかは「ユーザーエージェント」という情報を取得すると分かります。次のようなプログラムを、これまで作ってきたプログラムとは別の場所に打ち込んでみましょう。

var agent = navigator.userAgent
console.log(agent)

すると、例えば Windowsの場合は次のように表示されます。

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100

また、macOSの場合は次のように表示されます。

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3864.0 Safari/537.36

ここには、ブラウザーの種類やバージョンなどの他、OSの情報も含まれています。そこで、これをindexOfメソッドを使って検索しましょう。

var agent = navigator.userAgent
console.log(agent.indexOf('Windows')) // 13などかまたは -1

こうすると、Windowsでアクセスした場合は発見した文字位置(13文字目など)が、見つからなかった場合は -1が返されます。なお、大文字と小文字が混ざっているとややこしいので、toLowerCase()メソッドを使ってすべて小文字にしておくと良いでしょう。

var agent = navigator.userAgent.toLowerCase()
console.log(agent.indexOf('windows')) // 13などかまたは -1

Vue.jsのメソッドを定義する

では、これを使って先のv-ifでその時の状況に応じて true/falseを出し分けましょう。ここでは、「isPlatform」というメソッドを定義します。dataは削除してしまって良いでしょう。

<script>
var app = new Vue({
  el: "#app",
  methods: {
    isPlatform: function(platform) {
      var agent = navigator.userAgent.toLowerCase()
      return agent.indexOf(platform) > 0
    }
  }
})
</script>

これによって、次のように呼び出すとボタンの出し分けができます。

<a v-if="isPlatform('windows')" class="btn btn-primary btn-xl js-scroll-trigger" href="#about">Windows版</a>
<a v-if="isPlatform('macintosh')" class="btn btn-dark btn-xl js-scroll-trigger" href="#about">macOS版</a>

Windows/macOS以外の時にボタンが消えてしまう

これで一旦完成となりますが、このままでは Windows/macOS以外の場合、例えば iPadOSや Androidの時になにも表示されなくなります。

これを防ぐ方法にはいくつかありますが、ここではちょっと代わった方法として、先ほどのプログラムを「逆転」させましょう。つまり、「macOSではないときに、Windows版を表示」「Windowsではないとき、macOS版を表示」とします。

これにより、どちらでもない環境の時は両方のボタンが表示されるというわけです。

ではまずは、メソッドを変更しましょう。isPlatformisntPlatformに変更します。

<script>
var app = new Vue({
  el: "#app",
  methods: {
    isntPlatform: function(platform) {
      var agent = navigator.userAgent.toLowerCase()
      return agent.indexOf(platform) === -1
    }
  }
})
</script>

そして、ボタンからの呼び出しを逆にします。

<a v-if="isntPlatform('macintosh')" class="btn btn-primary btn-xl js-scroll-trigger" href="#about">Windows版</a>
<a v-if="isntPlatform('windows')" class="btn btn-dark btn-xl js-scroll-trigger" href="#about">macOS版</a>

これで完成です。ユーザーエージェントには、この他にもいろいろな情報が含まれています。是非、うまく活用して行きましょう。