Personal blog: raptazure.github. IO /#/post/17
I happened to see a post on V2EX about the electron vue Boilerplate, someone recommended quasar framework in the comment section, went to the official website for a look, a set of code can simultaneously do SPA, PWA, BEX, SSR, Hybrid Mobile apps and multi-Platform Desktop apps, although the idea of write once and deploy Everywhere has been seen many times, But the heavyweight framework of Vue suddenly made me want to give it a try, so let’s just do it.
What to do
- Todo already has Todoist for me, so let’s go with the Weather app (this is obviously an excuse). Here’s what it looks like.
- The main functions to be completed are: location and display the current geographical location weather, search for a location weather, background color and weather icon for different situations.
Setup project
- You have to go through
yarn global add @quasar/cli
Install the Quasar CLI. - through
quasar create <folder_name>
Create a new project and install dependencies. - use
quasar dev
Compile and run. The single-page application should have been compiled and opened automatically in the browser.
Design & Coding
- Because the function is relatively simple, so even the Web terminal, the content that needs to be displayed is not too much, according to the proportion of the phone design is good, long and narrow feeling, from top to bottom for the search bar, Logo and positioning and obtain the current location of the weather button/weather details.
- Since there are some things in the generated template that we don’t need, we’ll focus on the main battlefield first
src/layouts
和src/pages
The contents of the folder will be cleaned upsrc/layouts/MainLayout.vue
Initialize to the following code:
<template>
<q-layout view="lHh Lpr lFf">
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template>
<script>
export default {
name: "MainLayout",
data() {
return{}; }};</script>
Copy the code
- After that, the main task is
src/pages/index.vue
Look at the official documentation should be very easy to understand the following code, where../statics/skyline.png
It’s a town Sillhouette on Pixabayillustration, while the background of the progressive color can be passeduiGradientsLet’s make a selection.
<template>
<q-page class="flex column">
<div class="col q-pt-lg q-px-md">
<q-input
bottom-slots
v-model="search"
placeholder="Search"
dark
borderless
>
<template v-slot:before>
<q-icon name="my_location" />
</template>
<template v-slot:append>
<q-btn round dense flat icon="search" />
</template>
</q-input>
</div>
<template v-if="weatherData">
<div class="col text-white text-center">
<div class="text-h4 text-weight-light">Beijing</div>
<div class="text-h6 text-weitht-light">Clear</div>
<div class="text-h1 text-weight-thin q-my-lg relative-position">
<span>27</span>
<span class="text-h4 relative-position degree">° C</span>
</div>
</div>
<div class="col text-center">
<img src/>
</div>
</template>
<template v-else>
<div class="col column text-center text-white">
<div class="col text-h2 text-weight-thin">
Quasar
<br />Weather
</div>
<q-btn class="col" flat>
<q-icon left size="3em" name="my_location" />
<div>Find my location</div>
</q-btn>
</div>
</template>
<div class="col skyline"></div>
</q-page>
</template>
<script>
export default {
name: "PageIndex",
data() {
return {
search: "".weatherData: null}; }};</script>
<style lang="sass">.q-page background: linear-gradient(to bottom, #136a8a, #267871) .degree top: -44px .skyline flex: 0 0 100px background: url(.. /statics/skyline.png) background-size: contain background-position: center bottom</style>
Copy the code
-
So far, we have implemented the search bar (prototype), the weather (fake at this point) and the corresponding image (not yet added) when there is weather data, the app logo and location button when there is no weather data, and the illustration of the city at the bottom for decoration.
-
Now that you have a rough idea of what the application looks like, it’s time to implement various practical functions, including getting the current geographic location (latitude and longitude) and querying the weather for a specific location (both by city name and by latitude and longitude). If you want to use the OpenWeather API, you need to register your account and save the api-key. If you want to use the api-key, you need to use the. Follow the instructions to install and use app-extension-Dotenv, and remember to recompile in case the environment variables you set are not enabled.
-
Plugins: [“Loading”] can be accessed by this.$q.loading.
-
At the same time, we also calculated the bgClass attribute to switch the gradient background based on the day and night of the target city, so the SPA part is almost complete.
<template>
<q-page class="flex column" :class="bgClass">
<div class="col q-pt-lg q-px-md">
<q-input
bottom-slots
@keyup.enter="getWeatherBySearch"
v-model="search"
placeholder="Search"
dark
borderless
>
<template v-slot:before>
<q-icon @click="getLocation" name="my_location" />
</template>
<template v-slot:append>
<q-btn round dense flat @click="getWeatherBySearch" icon="search" />
</template>
</q-input>
</div>
<template v-if="weatherData">
<div class="col text-white text-center">
<div class="text-h4 text-weight-light">{{ weatherData.name }}</div>
<div class="text-h6 text-weitht-light">{{ weatherData.weather[0].main }}</div>
<div class="text-h1 text-weight-thin q-my-lg relative-position">
<span>{{ Math.round(weatherData.main.temp) }}</span>
<span class="text-h4 relative-position degree">° C</span>
</div>
</div>
<div class="col text-center">
<img
:src=" `https://openweathermap.org/img/wn/${weatherData.weather[0].icon}@2x.png` "
/>
</div>
</template>
<template v-else>
<div class="col column text-center text-white">
<div class="col text-h2 text-weight-thin">
Quasar
<br />Weather
</div>
<q-btn @click="getLocation" class="col" flat>
<q-icon left size="3em" name="my_location" />
<div>Find my location</div>
</q-btn>
</div>
</template>
<div class="col skyline"></div>
</q-page>
</template>
<script>
export default {
name: "PageIndex",
data() {
return {
search: "".weatherData: null.lat: null.lon: null.apiUrl: "https://api.openweathermap.org/data/2.5/weather".apiKey: process.env.API_KEY
};
},
computed: {
bgClass() {
if (this.weatherData) {
if (this.weatherData.weather[0].icon.endsWith("n")) {
return "bg-night";
} else {
return "bg-day"; }}}},methods: {
getLocation() {
this.$q.loading.show();
navigator.geolocation.getCurrentPosition(position= > {
this.lat = position.coords.latitude;
this.lon = position.coords.longitude;
this.getWeatherByCoords();
});
},
getWeatherByCoords() {
this.$q.loading.show();
this.$axios(
`The ${this.apiUrl}? lat=The ${this.lat}&lon=The ${this.lon}&appid=The ${this.apiKey}&units=metric`
).then(response= > {
this.weatherData = response.data;
this.$q.loading.hide();
});
},
getWeatherBySearch() {
this.$q.loading.show();
this.$axios(
`The ${this.apiUrl}? q=The ${this.search}&appid=The ${this.apiKey}&units=metric`
).then(response= > {
this.weatherData = response.data;
this.$q.loading.hide(); }); }}};</script>
<style lang="sass">.q-page background: linear-gradient(to bottom, #136a8a, #267871) &.bg-night background: linear-gradient(to bottom, #232526, #414345) &.bg-day background: linear-gradient(to bottom, #00b4db, #0083b0) .degree top: -44px .skyline flex: 0 0 100px background: url(.. /statics/skyline.png) background-size: contain background-position: center bottom</style>
Copy the code
More Platforms
Just writing a web app isn’t going to meet our expectations for the framework, so let’s start adapting to other platforms.
Electron – macOS
- Since I’m currently using macOS, it runs
quasar dev -m electron
You can build Weather App for macOS. (Laughter) - The initial window size can be passed
src-electron/main-process/electron-main.js
Width and height to make the application appear slimmer from the start. - But the ability to find a location doesn’t work because
geolocation api
Doesn’t work in electron, so, we need to pairgetLocation()
Make some changes, and you can passhttps://freegeoip.app
To get the location, and then it works:
getLocation() {
this.$q.loading.show();
if (this.$q.platform.is.electron) {
this.$axios.get("https://freegeoip.app/json/").then(response= > {
this.lat = response.data.latitude;
this.lon = response.data.longitude;
this.getWeatherByCoords();
});
} else {
navigator.geolocation.getCurrentPosition(position= > {
this.lat = position.coords.latitude;
this.lon = position.coords.longitude;
this.getWeatherByCoords(); }); }}Copy the code
Electron – Windows
- in
quasar.conf.js
In theelectron.package
addplatform: 'win32'
. - Run again
quasar build -m electron
Build the Windows version and open it with a virtual machine!
Cordova – iOS
- It must be installed
Xcode
Run,quasar dev -m ios
Can be debugged. - But it turns out that getting the location still doesn’t work because we didn’t install it
cordova-plugin-geolocation
In thesrc-cordova
Running in thecordova plugin add cordova-plugin-geolocation
And, insrc-cordova/config.xml
Add the location of ios in:
<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
<string>need location access to find things nearby</string>
</edit-config>
Copy the code
- The recompile run should work fine.
Cordova – Android
- It must be installed
Android Studio
Run,quasar dev -m android
Can be debugged. - However, it still doesn’t work to get the location. Check chrome debug and find that it is HTTP
quasar.config.js
In thedevSever.https
为true
Also note whether the Emulator’s Android version supports itgeolocation
。
Conclusion
To be honest, it is very attractive to implement the whole platform in one codebase. Although there will be various problems in the process of adaptation, it has saved a lot of manpower and resources (especially for simple applications). Incidentally, the above code can be found in this repository