Vue.jsとOpenStreetMapで1分おきに移動距離を表示するアプリ作成にtryしてみる(1)
以前、Vue.jsとLeaflet.jsとOpenStreetMapで現在位置を地図で表示するPWAを作成してみました。
今回は、このアプリを複数ページにして、1ページ目で現在地を地図で表示し、2ページ目で、1分おきに歩いた距離を表示し、さらに、今まで動いた距離を表示したいと思います。
- 1. ソースコードとDEMOサイト
- 2. 開発環境
- 3. 新規Vue.jsアプリの作成
- 4. leafletのインストール
- 5. src/views/Home.vueの編集
- 6. src/views/About.vueの編集
- 7. setInterval()の外で
let self = this
としてthisオブジェクトを別の変数に割り当てる(JavaScriptの"this") - 8. filterを用いて小数点以下3桁表示に変更
- 9. Bulmaを用いて表示を修正
- 10. 歩いた距離をlocalStorageに保存して永続化する
- 11. setInterval()に対するclearInterval()
- 12. ソースコードとDEMOサイト
ソースコードとDEMOサイト
ソースコード
https://github.com/adash333/vue-osmap-distance
DEMOサイト
https://laughing-shaw-6881f1.netlify.com/
開発環境
Windows 10 Pro
VisualStudioCode 1.37.1
git version 2.20.1.windows.1
nvm-windows 1.1.7
node 12.2.0
npm 6.9.0
yarn 1.16.0
@vue/cli 3.10.0
Node.jsをインストールした状態で、npm i -g @vue/cli でVue CLI(Version 3)をインストールしています。
新規Vue.jsアプリの作成
C:/vue/ フォルダをVisualStudioCodeで開き、Ctrl+@でコマンドプロンプトを開き、以下を入力します。
最初にマニュアル設定を選び、次の選択肢のうち以下の3つをスペースキーで追加して、後は、vue routerのHistoryモードのところ以外はEnterを連打します。(vue routerのHistoryモードは、n としておきます。 )
- Progressive Web App (PWA) Support
- Router
- Vuex
vue create vue-osmap-distance
いったん、開発サーバを起動して現在のページを確認します。
cd vue-osmap-distance
yarn serve
( または、npm run serve )
VisualStudioCodeのターミナル画面で、一旦、Ctrl+C => y + Enter でサーバを停止しておきます。
leafletのインストール
leaflet.jsは、OpenStreetMapを呼び出すために非常に便利なJavaScriptライブラリです。Vue.jsアプリでなくても、普通にindex.htmlから呼び出して利用することもできます。(参考: https://kita-note.com/leaflet-tutorial-1 )
今回は、以下を入力します。
yarn add leaflet
(または npm i leaflet --save)
参考: https://qiita.com/po3rin/items/3968f825f3c86f9c4e21
po3rin
2019年06月13日に更新
VueCLIからVue.js入門①【VueCLIで出てくるファイルを概要図で理解】
src/views/Home.vueの編集
まず、yarn serve して、ブラウザで http://localhost:8080/ を開いておきます。
写経元サイトのコードをコピペします。
http://のところだけhttps:// に変更しています。
(変更前)
(変更後)
地図は表示されましたが、HomeとAboutのリンクも消えてしまい、複数ページにできません。
試しに、src/components/Map.vue を新規作成し、 Home.vueの中身をほぼコピペしてみます。
また、さらにHome.vueも変更します。
→どうしても表示されず、うまくいきません。。。もう一度、写経元サイトを読み返してみると、以下のような記載がありました。
(Leaflet.jsでは、)html, body, #app { height: 100% } で地図を囲む全ての要素の height を 100% にしないと地図が表示されません。
参考:https://qiita.com/Satachito/items/929a63e9b266f6db7958
つまり、さらに、<style>のところに、#mapid を追加すればよいのかも、、、
ここまでのソースコード
https://github.com/adash333/vue-osmap-distance/tree/acca7ce6d65c0da55735afe91182d79d526848a1
src/views/About.vueの編集
Aboutページには、以下の3つを表示したいと思います。
- 現在地の緯度と経度
- 1分おきに移動した距離
- アプリを開いてから移動した距離の合計
まず、現在地の緯度経度をGeolocation APIを用いて取得して表示します。(参考:Vue.jsにてGeolocation APIで取得した値をdataプロパティに設定する)
次に、1分おきに移動した距離を表示したいと思います。setInterval()関数を用います。
(変更前)
(変更後)
Ctrl + Shift + I でconsole画面を見てみると、“Cannot set property 'lat2’ of undefined” とエラーが出ており、いろいろやったのですが、どうにもできませんでした。
どうやら、"this" に問題がありそうです。
setInterval()の外でlet self = this
としてthisオブジェクトを別の変数に割り当てる(JavaScriptの"this")
JavaScriptでよく出てくる this ですが、正直、まったくよくわかりません。以下のリンクを読んでみます。
https://www.sejuku.net/blog/29389
thisって何?使い方を覚えて、JavaScriptをもっと楽しく使おう!
マサト
2019/5/11
https://qiita.com/tsukishimaao/items/39d22fd9178546d6cdeb
@tsukishimaao
2014年02月01日に更新
windowオブジェクト
https://qiita.com/takeharu/items/9935ce476a17d6258e27
@takeharu
2015年12月07日に更新
JavaScriptの「this」は「4種類」??
今回の、setInterval(){} の中のthis.lat2がundefinedになってしまうことに対する解決策としては、
.bind()
を用いるlet self = this
としてthisオブジェクトを別の変数に割り当てる- アロー関数を用いる
の3つがあるそうです。let self = this
としてthisオブジェクトを別の変数に割り当てる方法が、一番分かりやすそうです。
(参考1:how to use setInterval in vue component)
(参考2:How to access the correct `this` inside a callback?)
以下のように書きなおしてみました。
しかし、これだと、最初の1分間(今だけ便宜的に20秒毎にしてあります)だけ、距離が(緯度, 経度)=(0, 0)からの距離になってしまいます。どうしたらよいでしょうか?(総距離から同じ値を引けばよいか???)
とりあえず、Netlifyにデプロイしてスマホでサイトを開き、位置情報を許可して、歩いてみたところ、とりあえずは以下のように、20秒ごとに、歩いた距離が表示されました。
さらに少しコードを変更して、最初の1分間で移動した距離を0 (最初の1分間はあきらめる、、、(爆))としました。
ここまでのソースコード
https://github.com/adash333/vue-osmap-distance/tree/19a83b9da3a70305b24fc26a2699e51db73253c2
filterを用いて小数点以下3桁表示に変更
Vue.jsのfilterを用いて、以下のようにします。
// <template>の一部
<h1>現在地</h1>
<p>緯度:{{latitude | round}}</p>
<p>経度:{{longitude | round}}</p>
// <script>の一部
filters: {
// 小数点以下を第3位に丸めるフィルタ
round: function (val) {
return Math.round(val * 1000) / 1000
}
}
Bulmaを用いて表示を修正
CSSフレームワークBulmaを用いるために、コマンドプロンプトで以下のようにbulmaをインストールします。
yarn add bulma
// npm install bulma でもOK
なんか、leaflet.jsとバッティングしそうですが、とりあえず見なかったことにして進みます。
public/index.htmlの</head>の直前に、以下のコードを挿入します。
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
(変更前)
(変更後)
次に、src/main.jsの6行目付近に以下のコードを追加します。
import './../node_modules/bulma/css/bulma.css';
これで、Vue.jsでbulmaとFontAwesome5が利用できるようになります。
参考:CodeSandboxのVue.jsでBulmaを利用する方法
src/App.vueと、src/components/about.vue を、bulmaを用いて少し変更します。
歩いた距離をlocalStorageに保存して永続化する
現時点では、ページを変更すると、それまで歩いた距離はリセットされて0になってしまうため、今まで歩いた距離をlocalStorageに保存するようにしてみたいと思います。
参考:
https://iwb.jp/javascript-vuejs-install-localstorage/
src/views/About.vue
// mounted() {} の最初のところに以下を挿入
if (localStorage.length) {
this.length = localStorage.length
}
// self.length = self.length + self.d の下に以下を挿入
localStorage.setItem('length', self.length)
setInterval()に対するclearInterval()
SPA(Single Page Application)の場合、一度setIntervalしたものは、全画面で有効になり続けるそうです。他のページに移動したときにsetInterval内の操作を中止したい場合には、
- data: {} の中で、interalId: undefined
- this.intervalId = setInterval(…)
- beforeDestroy() {} の中に、clearInterval(this.intervalId)
のように記載するそうです。
しかし、今回は、地図の画面に移動しても歩いた距離は計算し続けてほしいため、この実装は行わないことにしました。
参考:Vuejs ポーリングする時の注意点(@kimullaa 2018年05月30日に投稿)
ソースコードとDEMOサイト
ソースコード
https://github.com/adash333/vue-osmap-distance
DEMOサイト
https://laughing-shaw-6881f1.netlify.com/
参考:Netlifyにデプロイするときの設定
ディスカッション
コメント一覧
まだ、コメントがありません