Cara Membuat Aplikasi Cuaca GeoLocation Menggunakan Vue JS
OpenPublic API seperti OpenWeatherMap API, Google Maps Embed API, Random Quotes API, dan Hacker News API sangat berguna untuk memulai proyek sampingan atau menambahkan portofolio lain ke stack Anda.
splashScreen dan halaman Detail pada Aplikasi Geo Location Vue.js — https://gerimis-app.vercel.app/
Fitur pada Vue.js Geo Location Application — https://gerimis-app.vercel.app/
Kata pengantar
Aplikasi web atau aplikasi berbasis lokasi sangat umum di aplikasi web atau seluler apa pun. Dikombinasikan dengan fitur dan layanan lain, ini bisa menjadi aplikasi yang sangat kuat. API publik memiliki keuntungan dalam menggabungkan praktik pengembangan front-end ke dalam proyek dunia nyata dan membaginya dengan publik.
Anda mungkin sudah memiliki klon Instagram, Spotify, atau klon aplikasi lain dengan penyedia API publik. Cerita ini hanyalah referensi dari saya dengan manfaat OpenWeatherMap API, Google Map Embed API, dan Hacker News API dengan Vue.js, dan Anda mungkin ingin fokus pada proyek Anda berikutnya.
Target
Pahami cara memanfaatkan dan mengoptimalkan API publik untuk membuat dan membangun proyek aplikasi situs web.
Hapus penggunaan fitur API browser yang tersedia di semua browser yang menggunakan Vue.js. Buat sesuatu yang berguna untuk proyek situs web Anda dan pahami alur dan mekanisme di baliknya.
Fitur izin akses browser untuk menanyakan lokasi di perangkat Anda — https://gerimis-app.vercel.app/
Menangani izin permintaan dari aplikasi Anda melalui izin browser untuk menggunakan API geolokasi dari browser Anda.
Mengapa Vue.js dengan API publik?
Vue.js adalah kerangka kerja JavaScript open source populer yang dibuat oleh Evan You yang telah mendapatkan komunitas pengembang yang besar. Sangat mudah dipahami dalam ekosistem besar untuk mendukungnya.
Vue.js The Progressive JavaScript Framework
API Publik
Layanan API publik dapat digunakan secara publik dalam proyek yang memenuhi berbagai kebutuhan. Itu berisi layanan yang ingin saya gunakan dan integrasikan ke dalam aplikasi saya, tetapi saya membutuhkan layanan pihak ketiga yang tidak dimiliki aplikasi saya.
Google Maps Embed API yang disediakan oleh Google adalah layanan yang menggunakan peta yang disematkan di situs web dan tidak dikenai biaya. Google memiliki banyak hal untuk ditawarkan mengenai layanan peta dan layanan hebat lainnya.
Maps Embed API
OpenWeatherMap adalah API cuaca berbasis lokasi yang dapat memberikan informasi cuaca di mana pun Anda mengarahkan ke API proyek Anda dari koordinat lintang dan bujur. Untuk memulai proyek atau portofolio baru, ini adalah awal yang baik untuk membangun aplikasi dengan kemampuan API berbasis cuaca atau lokasi.
HackerNews API dibuat untuk memungkinkan pengembang membuat versi situs web HackerNews mereka sendiri yang berbeda dari versi aslinya. Banyak fitur dan format lengkap yang tersedia untuk mengambil data dari situs web HackerNews juga tersedia di situs web aslinya.
https://news.ycombinator.com/
Instal proyek Vue.js Dependensi
Vue.js versi 2 sangat penting agar proyek dapat bekerja. Manajemen status dengan Vuexis dan Vue Router memungkinkan Anda mengakses aplikasi dari browser klien. Artikel ini menggunakan [email protected] untuk aplikasinya.
Ini didasarkan pada desain yang mengutamakan seluler, jadi kami akan menggunakan Tailwind CSS untuk aplikasi ini. Ikon yang digunakan dalam aplikasi ini adalah ikon indah dari Phosphor Icons.
Modul lainnya adalah basis default untuk instalasi Vue.js. Ini adalah contoh bagus dari Mike Street untuk memulai penyimpanan lokal di Vuex, karena contoh manajemen data menggunakan penyimpanan lokal.
Ini semua modul node yang terdaftar dalam file package.json.
{
"name": "gerimis-app",
"version": "1.0.3",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"phosphor-vue": "^1.4.0",
"vue": "^2.6.11"
},
"devDependencies": {
"@tailwindcss/postcss7-compat": "^2.0.2",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"autoprefixer": "^9",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"postcss": "^7",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2",
"vue-router": "^3.5.2",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.6.2"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
Untuk menginstal modul node untuk proyek ini, ketikkan yarn install atau npm install. konfigurasiah itu, Anda perlu menyiapkan beberapa konfigurasi dari OpenWeatherMap dan Google MapEmbed API. konfigurasiah instalasi modul selesai, ketik yarn serve atau npm runserve untuk menjalankan dan memulai pengembangan proyek.
Struktur direktori menggunakan tree command:
.
├── babel.config.js
├── jsconfig.json
├── package.json
├── postcss.config.js
├── public
│ ├── favicon.ico
│ ├── favicon.png
│ └── index.html
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── css
│ │ │ └── tailwind.css
│ │ └── icon-search.svg
│ ├── components
│ │ ├── Dashboard.vue
│ │ ├── Detail.vue
│ │ ├── Home.vue
│ │ ├── Search.vue
│ │ └── global
│ │ └── Footer.vue
│ ├── constants
│ │ ├── actionTypes.js
│ │ ├── env.js
│ │ └── statusTypes.js
│ ├── main.js
│ ├── store
│ │ └── index.js
│ └── utils
│ └── index.js
└── tailwind.config.js
konfigurasi API key OpenWeatherMap
Silakan masuk atau daftar ke OpenWeatherMap untuk mendapatkan key aplikasi ini. Klik API key Saya di menu dan klik Hasilkan untuk membuat key.
OpenWeatherMap API Dashboard pada Aplikasi Cuaca Lokasi Geo Vue.js
Konfigurasi Google Console Maps Embed API key
Masuk ke Google Developer Console dan jelajahi bagian API untuk mengaktifkan Maps Embed API untuk aplikasi ini. Google API memiliki batas tingkat permintaan 1000 untuk penggunaan gratis. Jika tidak, Anda akan dikenakan biaya untuk terus menggunakan API.
Karena kami menggunakan Embed API untuk tujuan ini, kami memberikan permintaan tak terbatas ke API ini secara gratis, jadi tidak ada masalah. Di bawah ini adalah tautan ke biaya layanan Google API.
Developer Console Google Cloud Platform
Segera konfigurasiah Anda membuat key akses Maps Embed API dan menggunakannya dalam proyek Anda, Anda akan dapat melihat jumlah permintaan di dasbor Google API Anda.
Google Cloud API dan Services Dashboard
konfigurasi itu, ada pengaturan yang memungkinkan Anda untuk mengakses bagian kredensial dan daftar putih situs web yang menggunakan layanan API ini. Jika Anda mengelola URL situs web Anda di field URL itu akan tersedia di Google Maps API. Salin API key dan Kode di bagian VUE_APP_API_GMAP_KEY dari file .env Anda.
konfigurasi variabel environtment
Buat .env.local di direktori root proyek Vue.js Anda, atau salin file dan variabel dari file .env.local-example. Secara otomatis diabaikan oleh git untuk mengkomit file ke repositori. Dari dokumentasi resmi Vue.js dan praktik terbaik, jangan letakkan variabel sensitif di file .env, terutama repositori git publik yang terbuka.
Jika Anda menggunakan Vercel atau Jamstack statik host, mereka biasanya menyediakan pengaturan proyek untuk menempatkan variabel environtment server pada host.
VUE_APP_API_OMAP_KEY = YourRandomOmapKeyAPI
VUE_APP_API_GMAP_KEY = YourRandomGmapEmbedAPI
Variabel-variabel ini dapat ditemukan dalam kode sumber di sini di .env.local-example. Ganti variabel dengan API key resmi.
Gabungkan OpenWeatherMap API dengan Google MapsStatic API
Buka atau buat file di src/constants/env.js dan Kode URL dan variabel key pribadi dari Google Developer Console dan OpenWeatherMap.
Variabel dalam file .env diekspos dari file Vue dengan sintaks process.env.VUE_APP_API_OMAP_KEY dan process.env.VUE_APP_API_GMAP_API.
export const API_OMAP_BASE = 'https://openweathermap.org/'
export const API_GMAP_BASE = 'https://www.google.com/'
export const API_OMAP_URL = 'https://api.openweathermap.org/data/2.5/weather?'
export const API_GMAP_URL = 'https://www.google.com/maps/embed/v1/place?'
export const API_OMAP_KEY = process.env.VUE_APP_API_OMAP_KEY
export const API_GMAP_KEY = process.env.VUE_APP_API_GMAP_KEY
Variabel-variabel ini dapat ditemukan di ./constants/env.js dalam kode sumber di sini .
Kode App.vue untuk proyek Anda
App.vue default menangani antarmuka utama aplikasi dan komponen <router-view>. Ini akan memuat semua status, variabel, dan penanganan kesalahan yang diperlukan oleh aplikasi proyek Vue.js Anda.
<template>
<div id="app" class="main-app">
<router-view v-if="!errors && onLine" />
<div
v-else
class="flex items-center justify-center h-screen xl:w-1/2 mx-auto px-6"
>
<h1 class="text-3xl md:text-6xl md:font-bold text-center">
<span class="hidden">{{ errors }}</span>
<small class="text-lg md:text-3xl block mt-4"
>Please re-check your internet or your browser permission to
continue.</small
>
<small class="w-full"
><button
class="text-xl underline hover:no-underline"
v-on:click="refresh()"
>
Reload
</button></small
>
</h1>
</div>
<div
v-if="!onLine"
class="border rounded-md w-1/3 mx-auto mb-2 py-1 px-2 fixed top-2 right-2 text-md"
>
you are offline...
</div>
<div
v-if="showBackOnline"
class="border rounded-md w-1/3 mx-auto mb-2 py-1 px-2 fixed top-2 right-2 text-md"
>
back online...
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'App',
data: function() {
return {
locationLatLong: {},
getLocation: false,
cityName: '',
errors: null,
onLine: navigator.onLine,
showBackOnline: false
}
},
methods: {
getWeatherByLocation() {
const { setErrors, $store } = this
if (!('geolocation' in navigator)) {
setErrors('Geolocation is not available.')
} else {
this.getLocation = true
navigator.geolocation.getCurrentPosition(
pos => {
this.getLocation = false
this.locationLatLong = pos
$store.dispatch('getCurrentCity', {
lat: `${pos.coords.latitude}`,
long: `${pos.coords.longitude}`
})
},
err => {
this.getLocation = false
setErrors(err.message)
}
)
}
},
refresh() {
return this.$router.go()
},
setErrors(errors) {
this.errors = errors
},
updateOnlineStatus(e) {
const { type } = e
this.onLine = type === 'online'
}
},
created() {
const vm = this
vm.getWeatherByLocation()
},
watch: {
onLine(v) {
if (v) {
this.showBackOnline = true
setTimeout(() => {
this.showBackOnline = false
}, 1000)
}
}
},
mounted() {
window.addEventListener('online', this.updateOnlineStatus)
window.addEventListener('offline', this.updateOnlineStatus)
},
beforeDestroy() {
window.removeEventListener('online', this.updateOnlineStatus)
window.removeEventListener('offline', this.updateOnlineStatus)
},
computed: {
...mapState({
city: state => state.currentCity.data
})
}
}
</script>
App.vue from the Vue.js application
Code fungsi utilitas proyek
Anda tidak perlu berulang kali membuat kode fitur di seluruh file kode sumber, karena penting untuk membuat utilitas untuk proyek Anda. Metode ini juga membantu mengoptimalkan ukuran file proyek Anda.
Buat atau tambahkan file ke direktori ./src/utils/index.js dan tempatkan kode utilitas yang dapat Anda gunakan di file apa pun.
// Celcius to Fahrenheit function
export function cToF(celsius) {
const cTemp = celsius
const cToFahr = (cTemp * 9) / 5 + 32
return cToFahr
}
// Fahrenheit to Celcius function
export function fToC(fahrenheit) {
const fTemp = fahrenheit
const fToCel = ((fTemp - 32) * 5) / 9
return fToCel.toFixed(2)
}
// JSON Parse function
export function jsonParse(data = '') {
return JSON.parse(JSON.stringify(data))
}
Utility files pada aplikasi Vue.js
Develop API panggil Libraru pada Vuex Store
Untuk manajemen status dan penyimpanan di Vue.js, menggunakan Vuex sudah mencakup semua yang Anda perlukan untuk menyiapkan proyek ini.
Saya menggunakan metode pengambilan javascript untuk menangani permintaan ke server API, tetapi saya dapat memilih library seperti Axios untuk permintaan tersebut.
Vue.js memiliki direktori default untuk manajemen status di ./store/index.js.
import Vue from 'vue'
import Vuex from 'vuex'
import TYPES from '@/constants/actionTypes'
import STATUS from '@/constants/statusTypes'
import {
API_OMAP_URL,
API_OMAP_KEY,
API_NEWS_URL,
API_QUOTE_URL
} from '@/constants/env'
import { jsonParse } from '@/utils'
const { INIT, LOADING, SUCCESS, ERROR } = STATUS
const {
INITIALIZE_STORE,
SET_TEMP,
GET_CURRENT_CITY_LOAD,
GET_CURRENT_CITY_RES,
GET_CURRENT_CITY_ERR,
GET_SEARCH_CITY_LOAD,
GET_SEARCH_CITY_RES,
GET_SEARCH_CITY_ERR,
GET_NEWS_LOAD,
GET_NEWS_RES,
GET_NEWS_ERR,
GET_QUOTE_LOAD,
GET_QUOTE_RES,
GET_QUOTE_ERR,
SET_CITIES,
REMOVE_CITY
} = TYPES
/* You change units here */
const apiUrl = `${API_OMAP_URL}appid=${API_OMAP_KEY}&units=imperial`
Vue.use(Vuex)
export default new Vuex.Store({
state: {
currentCity: {
data: {},
error: null,
status: INIT
},
currentSearch: {
data: [],
error: null,
status: INIT
},
cities: [],
news: { data: [], error: null, status: INIT },
quote: { data: [], error: null, status: INIT },
setup: { temp: 'F' }
},
getters: {
getCurrentCity: state => jsonParse(state.currentCity.data),
getCurrentSearch: state => jsonParse(state.currentSearch.data),
getNews: state => jsonParse(state.news.data),
getTemp: state => jsonParse(state.setup.temp)
},
actions: {
async getCurrentCity({ commit }, params) {
try {
const url = `${apiUrl}&lat=${params.lat}&lon=${params.long}`
commit(GET_CURRENT_CITY_LOAD)
await fetch(url, { mode: 'cors' })
.then(async response => {
if (!response.ok && response.status !== '200') {
commit(GET_CURRENT_CITY_ERR, response.statusText)
} else {
commit(GET_CURRENT_CITY_RES, await response.json())
}
})
.catch(function(error) {
commit(GET_CURRENT_CITY_ERR, error.TypeError)
})
} catch (err) {
commit(GET_CURRENT_CITY_ERR, err.TypeError)
}
},
async getCurrentSearch({ commit }, params) {
try {
const url = `${apiUrl}&q=${params.query}`
commit(GET_SEARCH_CITY_LOAD)
await fetch(url, { mode: 'cors' })
.then(async response => {
if (!response.ok && response.status !== '200') {
commit(GET_SEARCH_CITY_ERR, response.statusText)
} else {
const result = await response.json()
commit(GET_SEARCH_CITY_RES, result)
commit(SET_CITIES, result)
}
})
.catch(function(error) {
commit(GET_SEARCH_CITY_ERR, error.TypeError)
})
} catch (err) {
commit(GET_SEARCH_CITY_ERR, err.TypeError)
}
},
async getNews({ commit }) {
try {
const apiNewsUrl = `${API_NEWS_URL}topstories.json?print=pretty`
commit(GET_NEWS_LOAD)
await fetch(apiNewsUrl, {
mode: 'cors'
})
.then(async response => {
if (!response.ok && response.status !== '200') {
commit(GET_NEWS_ERR, response.statusText)
} else {
const result = await response.json()
const collection = result.slice(0, 5).map(id =>
fetch(`${API_NEWS_URL}item/${id}.json`, {
mode: 'cors'
})
.then(async response => {
return await response.json()
})
.catch(function(error) {
commit(GET_NEWS_ERR, error.TypeError)
})
)
commit(GET_NEWS_RES, await Promise.all(collection))
}
})
.catch(function(error) {
commit(GET_NEWS_ERR, error.TypeError)
})
} catch (err) {
commit(GET_NEWS_ERR, err.TypeError)
}
},
async getQuote({ commit }) {
try {
const url = `${API_QUOTE_URL}random`
commit(GET_QUOTE_LOAD)
await fetch(url, { mode: 'cors' })
.then(async response => {
if (!response.ok && response.status !== '200') {
commit(GET_QUOTE_ERR, response.statusText)
} else {
commit(GET_QUOTE_RES, await response.json())
}
})
.catch(function(error) {
commit(GET_QUOTE_ERR, error.TypeError)
})
} catch (err) {
commit(GET_QUOTE_RES, err.TypeError)
}
},
async setTemp({ commit }, params) {
commit(SET_TEMP, params)
},
async removeCity({ commit }, params) {
try {
commit(REMOVE_CITY, params)
} catch (err) {
commit(GET_SEARCH_CITY_ERR, err.TypeError)
}
}
},
mutations: {
[INITIALIZE_STORE](state) {
if (localStorage.getItem('store')) {
this.replaceState(
Object.assign(state, JSON.parse(localStorage.getItem('store')))
)
} else {
localStorage.setItem('store', JSON.stringify(state))
}
},
[SET_TEMP](state, payload) {
state.setup.temp = payload
},
[GET_CURRENT_CITY_LOAD](state) {
state.currentCity.status = LOADING
state.currentCity.error = null
},
[GET_CURRENT_CITY_RES](state, payload) {
if (state.cities.length === 0) {
state.cities = [payload]
}
state.currentCity.data = payload
state.currentCity.status = SUCCESS
state.currentCity.error = null
localStorage.setItem('store', JSON.stringify(state))
},
[GET_CURRENT_CITY_ERR](state, error) {
state.currentCity.status = ERROR
state.currentCity.error = error
state.currentCity.data = null
},
[GET_SEARCH_CITY_LOAD](state, payload) {
state.currentSearch.data = payload
state.currentSearch.status = LOADING
state.currentSearch.error = null
},
[GET_SEARCH_CITY_RES](state, payload) {
state.currentSearch.data = payload
state.currentSearch.status = SUCCESS
state.currentSearch.error = null
localStorage.setItem('store', JSON.stringify(state))
},
[GET_SEARCH_CITY_ERR](state, error) {
state.currentSearch.status = ERROR
state.currentSearch.error = error
},
[GET_NEWS_LOAD](state, payload) {
state.news.data = payload
state.news.status = LOADING
state.news.error = null
},
[GET_NEWS_RES](state, payload) {
state.news.data = payload
state.news.status = SUCCESS
state.news.error = null
localStorage.setItem('store', JSON.stringify(state))
},
[GET_NEWS_ERR](state, error) {
state.news.status = ERROR
state.news.error = error
},
[GET_QUOTE_LOAD](state, payload) {
state.quote.data = payload
state.quote.status = LOADING
state.quote.error = null
},
[GET_QUOTE_RES](state, payload) {
state.quote.data = payload
state.quote.status = SUCCESS
state.quote.error = null
localStorage.setItem('store', JSON.stringify(state))
},
[GET_QUOTE_ERR](state, error) {
state.quote.status = ERROR
state.quote.error = error
},
[SET_CITIES](state, payload) {
state.cities = [
payload,
...state.cities.filter(city => city.id !== payload.id)
]
localStorage.setItem('store', JSON.stringify(state))
},
[REMOVE_CITY](state, payload) {
state.cities = state.cities.filter(city => city.id !== payload.id)
localStorage.setItem('store', JSON.stringify(state))
}
}
})
Vue and Vuex store di Aplikasi Vue.js
Storage akan menghandle request dari API_OMAP_URL, API_OMAP_KEY, API_NEWS_URL, and API_QUOTE_URL dari environment URL constants ketikamemetakan tanggapan ke dalam negara bagian.
Membuat Halaman dan Routes
Fitur pencarian dan daftar di Aplikasi Cuaca Geo Location Vue.js — https://gerimis-app.vercel.app/
Halaman dan Routes di Aplikasi Cuaca Geo Location Vue.js — https://gerimis-app.vercel.app/
Gunakan Vue router vue-router untuk mengatur routes untuk menyediakan semua routes halaman yang tersedia di aplikasi Anda. Buka src\main.js default Vue.js dan tentukan semua routes, termasuk impor yang diperlukan.
halaman
- Beranda.vue
- Dashboard.vue
- Detail.vue
- Cari.vue
Beranda akan menjadi layar pembuka untuk aplikasi Gerimis Vue.js Anda. Klik disini untuk melihat tautan sumber Vue.js.
Dasboard akan menjadi halaman utama tempat menyimpan riwayat peta. Klik disini untuk melihat tautan sumber Vue.js.
Halaman detail akan menjadi halaman lokasi peta tempat Anda dapat mencari semua data cuaca saat ini. Klik disini untuk melihat tautan sumber Vue.js.
Halaman pencarian adalah halaman untuk mencari lokasi berdasarkan nama dan menyimpannya di pencarian lokasi pada halaman dashboard. Klik disini untuk melihat tautan sumber Vue.js.
Routes
Karena aplikasi ini memiliki 5 halaman, routes terdiri dari 5 routes yang mendefinisikan:
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
import App from './App.vue'
import './assets/css/tailwind.css'
Vue.config.productionTip = false
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
name: 'home',
component: () => import('./components/Home.vue')
},
{
path: '/dashboard',
name: 'dashboard',
component: () => import('./components/Dashboard.vue')
},
{
path: '/search',
name: 'search',
component: () => import('./components/Search.vue')
},
{
path: '/detail',
name: 'detail',
component: () => import('./components/Detail.vue')
},
{
path: '/detail/:id',
name: 'detailId',
component: () => import('./components/Detail.vue')
}
]
})
new Vue({
store,
router,
render: h => h(App),
beforeCreate() {
this.$store.commit('INITIALIZE_STORE')
}
}).$mount('#app')
main.js file for Vue.js routes
Deploy aplikasi
Anda dapat membuat situs web ini tersedia untuk umum menggunakan Vercel dan Netlify. Ini menyediakan hosting situs web statis gratis untuk kerangka kerja berbasis JavaScript.
Membangun NuxtJS dan memulai perintah di Vercel dan Netlify
Masuk ke dasbor Vercel atau Netlify Anda, atur repositori, variabel environtment, dan cabang dengan perintah build atau start. Bergantung pada kerangka kerja, seperti NuxtJS, perintah generate membuat file statis.
environtment produksi untuk environtment kredensial di .env harus dipindahkan ke pengaturan layanan ini.
Perintah build dan deploy Vue.js adalah yarn serve atau npm run serve secara default. Vercel akan secara otomatis mendeteksi atau membaca skrip di package.json file aplikasi Vue.js Anda.
Membangub Vue.js dan deployment settings
konfigurasi perintah build, Vercel atau Netlify akan memberi tahu Anda bahwa situs web sudah di-deploy secara langsung.
Hal yang harus dilakukan
Ada beberapa hal yang dapat Anda lakukan untuk meningkatkan aplikasi ini.
- Tingkatkan ke Vue 3 dengan fitur baru.
- Meningkatkan kecepatan pemuatan panggilan API.
- Tambahkan fitur baru seperti halaman pengaturan.
Kesimpulan, kode sumber, dan demo
Disimpulkan bahwa ini memungkinkan aplikasi web Vue.js untuk menangani kemampuan geoposisi dari API browser dan menggabungkannya dengan API publik lainnya.
Apabila ada yang terlewat anda bisa melihat Kode sumber dan tautan demo
sumber: https://javascript.plainenglish.io/how-to-build-vuejs-geo-location-weather-application-f65f5cc2fa4f