偶然在 v2ex 看到一个关于 electron-vue boilerplate 的帖子,评论区有人推荐了 quasar 这个框架,去官网看了看,一套代码可以同时搞 SPA,PWA,BEX,SSR,Hybrid Mobile App 和 Multi-platform Desktop App,虽然 write once, deploy everywhere 的想法已经见到很多次了,但是这个 Vue 的重量级框架突然让我有了上手试一试的冲动,不如就果断搞起来吧。
yarn global add @quasar/cli 安装 Quasar CLI。quasar create <folder_name> 建立新项目并安装依赖。quasar dev 编译运行,此时应该已经编译了单页应用并且在浏览器自动打开了。
src/layouts 和 src/pages 文件夹里的内容进行一下清理,将 src/layouts/MainLayout.vue 初始化为如下代码:<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>
复制代码src/pages/index.vue 了,看看官方文档应该能很轻松地看懂如下代码,其中 ../statics/skyline.png 为 pixabay 上的一幅 town sillhouette 的 illustration,而背景的渐进色可以通过 uiGradients 进行选取。<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>
复制代码至此,我们实现了搜索栏(样子货),实现了当有天气数据时显示天气(此时为假数据)和对应的图片(尚未添加),没有天气数据的时候显示应用 logo 并显示定位按钮,最底部还有城市的 illustration 来做装饰。
现在,应用的大体样子已经有了,接下来就是要实现各种实际功能,包括获取当前的地理位置(经纬度),查询特定位置的天气(包括按照城市名查询和按照经纬度查询)。为此,需要 OpenWeather API 的帮助,先要去官网注册账号并保存下 api-key,而提到 api-key 啊,就要用 .env 来设置环境变量,以免推到 GitHub 上后泄露个人信息,正好官网也是很贴心地提供了 app-extension-dotenv,按照说明安装并使用即可,同时记得重新编译一下以防设置的环境变量没有启用。
查询时的加载效果,框架已经集成了,在 quasar.conf.js 插件列加上 plugins: ["Loading"] 后即可通过 this.$q.loading 进行访问。
与此同时,我们还通过计算属性 bgClass 来实现了根据目标城市的白天和夜间切换不同的渐变背景,至此,SPA 的部分已经基本完成了。
<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(
`${this.apiUrl}?lat=${this.lat}&lon=${this.lon}&appid=${this.apiKey}&units=metric`
).then(response => {
this.weatherData = response.data;
this.$q.loading.hide();
});
},
getWeatherBySearch() {
this.$q.loading.show();
this.$axios(
`${this.apiUrl}?q=${this.search}&appid=${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>
复制代码仅仅写完网页版应用肯定是不能满足我们对这个框架的期望啊,接下来就开始适配其他的平台吧。
quasar dev -m electron 即可构建 Weather App for macOS(笑)src-electron/main-process/electron-main.js 中的 width 与 height 来进行修改,让应用一开始就显得更苗条。geolocation api 在 electron 应用中不起作用,所以,我们需要对 getLocation() 进行一下修改,此时可以通过 https://freegeoip.app 来获取地理位置,之后就能正常工作: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();
});
}
}
复制代码quasar.conf.js 中的 electron.package 中添加 platform: 'win32'。quasar build -m electron 构建 Windows 版本,然后就可以用虚拟机打开啦!Xcode,运行 quasar dev -m ios 即可进行调试。cordova-plugin-geolocation,在 src-cordova 中运行 cordova plugin add cordova-plugin-geolocation,并在 src-cordova/config.xml 中 ios 的位置添加:<edit-config target="NSLocationWhenInUseUsageDescription" file="*-Info.plist" mode="merge">
<string>need location access to find things nearby</string>
</edit-config>
复制代码Android Studio,运行 quasar dev -m android 即可进行调试。quasar.config.js 中的 devSever.https 为 true,同时也要注意模拟器的安卓版本是否支持 geolocation 。说实话,一套 codebase 就能搞全平台还是非常具有吸引力的,虽然进行适配的过程也会遇到各种各种的问题,但是相对来说已经节省了大量的人力物力(特别是功能比较简单的应用)。顺便,以上代码可以在这个仓库找到~
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26692020/viewspace-3131819/ ,如需转载,请注明出处,否则将追究法律责任。