±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÍøÂ磬±¾ÎÄÖ÷Òª½éÉÜÁËElectron
ͨ¹ý°Ñ Chromium ºÍ Node.js ×éºÏµ½Ò»¸öÔËÐÐʱÀ´ÊµÏÖÕâÒ»µã£¬²¢ÇÒ¿ÉÒÔΪ
Mac¡¢Windows ºÍ Linux ´ò°üÓ¦ÓóÌÐò ¡£ |
|
ΪÁË¿ìËÙÈëÃÅ£¬ÎÒʹÓÃÁË Greg Holguin µÄ electron-vue
Ñù°å¡£Ëü¸ø¿ª·¢ÈËÔ±ÌṩÁË vue-cli scanffolding¡¢³£¼ûµÄ Vue ²å¼þ¡¢´ò°üÆ÷¡¢²âÊÔ¡¢¿ª·¢¹¤¾ßºÍÆäËû¹¦ÄÜ¡£
ÎÒÃÇÒª¹¹½¨Ê²Ã´?
ÎÒÃÇÒª¹¹½¨Ò»¸ö¸úÉÏһƪÎÄÕÂÖÐËùÊöµÄÒ»ÑùµÄÓ¦ÓóÌÐò£¬»ùÓÚ OpenWeatherMap
API µÄ¸ÃÓ¦ÓóÌÐòÓÃÀ´²é¿´Óû§ËùÑ¡Ôñ³ÇÊеÄÌìÆøÇé¿ö¡£
°²×°
Electron-vue Ñù°åÊÇ×÷Ϊ VueCLI 2.x µÄÄ£°å¹¹½¨µÄ£¬°üÀ¨×Ô¶¨ÒåÓ¦ÓóÌÐòµÄÑ¡Ïî¡£Òò´Ë£¬ÐèÒª½øÐÐÈ«¾Ö°²×°£º
Èç¹ûϲ»¶Óà VueCLI µÄ×îа汾£¬¾ÍÐèÒª°²×°È«¾ÖÍøÇÅ£º
npm
install -g @vue/cli @vue/cli-init |
È»ºó£¬³õʼ»¯ÄãµÄÏîÄ¿£º
vue
init simulatedgreg/electron-vue weather-app |
Õ⽫Æô¶¯Ò»¸ö°²×°ÏîÄ¿£¬ÆäÖаüÀ¨ÐèÒªÄã×ö³öµÄ¼¸¸öÑ¡Ôñ¡£

ÆäÖкܿáµÄÊÇ£¬Èç¹ûÐèҪһЩ³£ÓõIJå¼þºÍ¿â£¬±ÈÈç axios£¬¿ÉÒÔÔÚ°²×°¹ý³ÌÖÐÑ¡ÔñËüÃÇ¡£
¼¸ºõËùÓеÄÑ¡Ôñ¶¼ºÜÃ÷È·£¬µ«ÊÇÓÐÒ»¸öÎÊÌ⣺

ÎÒ¾ö¶¨ËÑË÷һϣ¬ÔÚ StackOverflow ÉÏÕÒµ½ÁËÒ»¸öÓÐÓõÄÏßË÷¡£¸ù¾ÝÕâ¸öÏßË÷£¬¿´ÆðÀ´ electron
¹¹½¨Æ÷£¨electron-builder£©¸üÊʺÏÎÒ£¬Òò´Ë£¬ÎҾ͸ÄÓÃËüÁË¡£
ÉèÖÃÏîÄ¿ºó£¬ÐèÒª´ò¿ªÓ¦ÓóÌÐòËùÔÚµÄÎļþ¼Ð£¬ÔËÐÐ npm install »ò yarn install£¬ÏÖÔÚÎÒÃÇ×¼±¸ºÃÁË¡£
Á˽âÓ¦ÓóÌÐò½á¹¹
°²×°Íê³Éºó£¬¿ÉÒÔÔÚ src Öп´µ½Á½¸öÎļþ¼Ð main ºÍ renderer£¬Electron Ö÷½ø³ÌÐèÒªÓõ½µÚÒ»¸ö¡£
¸ù¾Ý electron-vue µÄÎĵµ£¬ÔÚ Electron ÖÐÔËÐÐ package.json Ö÷½Å±¾µÄ½ø³Ì±»³ÆÎªÖ÷½ø³Ì¡£ÔÚÖ÷½ø³ÌÖÐÔËÐеĽű¾¿ÉÒÔͨ¹ý´´½¨
web Ò³ÃæÀ´ÏÔʾ GUI¡£
ÔÚ main Îļþ¼ÐÖÐÓÐÁ½¸öÎļþ£ºindex.js ºÍ index.dev.js¡£µÚÒ»¸öÊÇÄãµÄÓ¦ÓóÌÐòµÄÖ÷Îļþ£¬ÊÇ
electron Æô¶¯ÓõÄÎļþ¡£ËüÒ²±»ÓÃ×ö webpack µÄÉú²úÈë¿ÚÎļþ¡£ËùÓÐÖ÷ÒªµÄÁ÷³Ì¹¤×÷¶¼Ó¦¸Ã´ÓÕâÀ↑ʼ¡£
¶ø index.dev.jsis רÃÅÓÃÓÚ¿ª·¢£¬ÒòΪËü°²×°ÁË electron-debug ºÍ vue-devtools¡£ÔÚ¿ª·¢Ó¦ÓóÌÐòʱ£¬¿ÉÒÔ²»ÓÃÀí²ÇËü¡£
ÁíÍ⣬äÖȾÆ÷£¨renderer£©½ø³ÌÐèÒª renderer Îļþ¼Ð¡£
ÓÉÓÚ Electron ʹÓà Chromium À´ÏÔʾ web Ò³Ãæ£¬Òò´ËÒ²Óõ½ÁË Chromium
µÄ¶à½ø³Ì¼Ü¹¹¡£Electron ÖеÄÿ¸ö web Ò³Ãæ¶¼ÔÚ×Ô¼ºµÄ½ø³ÌÖÐÔËÐУ¬ÕâЩ½ø³Ì±»³ÆÎªäÖȾÆ÷½ø³Ì¡£
ÕýÈçÄã¿ÉÄÜ×¢Òâµ½µÄÊÇ£¬ËüÊǸö¡°Õý³£µÄ¡±Vue Ó¦ÓóÌÐò½á¹¹£¬ÓµÓÐ assets ºÍ components
Îļþ¼Ð£ºmain.js ºÍ App.vue Îļþ¡£ÕâÊǺóÕߵĽṹ£º
<template>
<div id="app">
<landing-page></landing-page>
</div>
</template>
<script>
import LandingPage from '@/components/LandingPage'
export default {
name: 'weather-app',
components: {
LandingPage
}
}
</script>
<style>
/* CSS */
</style> |
Èç¹û³¢ÊÔÔËÐÐ dev ÈÎÎñ£¬½«»áµÃµ½ÒÔϽá¹û£º

Òò´Ë£¬ÕâÀïÓÐÒ»¸öµÇÂ¼Ò³Ãæ£¨landing-page£©×é¼þ£¬Ò²¿ªÆôÁË¿ª·¢¹¤¾ß£¨devtools£©¡£ÏÖÔÚ£¬ÎÒÃÇ¿ÉÒԸıäËüÁË¡£
¿ìËÙ¹¹½¨£¨scaffolding£©Ó¦ÓóÌÐò
Óë Vuido ²»Í¬£¬Electron Ö§³ÖµÄÓ¦ÓóÌÐòÊÇÓà HTML ±êÇ©¶ø²»ÊÇÓñ¾»ú×é¼þ¹¹½¨µÄ¡£Òò´Ë£¬ÎÒÃǽ«´´½¨Ò»¸öÓëͨ³£µÄ
web Ó¦ÓóÌÐòÀàËÆµÄ½á¹¹£¬²¢Óà CSS À´½øÐÐÑùʽÉè¼Æ¡£
Çë×¢Ò⣺ÎÒûÓÐÌØÒâ°²×°ÈκΠCSS ¿ò¼Ü»ò×é¼þ¿â£ºÎÒÏ£ÍûÔÚûÓÐÌí¼ÓÈκβ»Í¬µÄÒÀÀµÏîµÄÇé¿öÏ£¬±È½ÏһϰüµÄ´óС¡£ÔÚÁ½¸öÏîÄ¿ÖÐΨһÓõ½µÄ¿âÊÇ
axios¡£
µÚÒ»²½ÊÇÈ¥µôµÇÂ¼Ò³Ãæ×é¼þ¡£È»ºóÎÒÌí¼ÓÁËÒ»¸ö¼òµ¥µÄÊäÈë×ֶκÍÒ»¸ö°´Å¥£º
<div
id="app">
<p>Enter the city name to check current
weather in it</p>
<section class="weather-input">
<input type="text" v-model="query">
<button :disabled="!query.length">Check</button>
</section>
</div> |

ÎÒÃÇÔÚÊý¾ÝÖÐÓиö²éѯ£¨query£©ÊôÐÔÀ´´¦ÀíÓû§ÊäÈ룬ÎÒÃǽ«°Ñ¸Ã²éѯ×÷Ϊ²ÎÊý£¬½øÐÐ API µ÷Óá£
½øÐÐ API µ÷ÓÃ
ÎÒʹÓÃÁË OpenWeatherMap µ±Ç°ÌìÆø API¡£ËüÌṩºÜ¶à²»Í¬µÄÐÅÏ¢£¬¿ÉÒÔµã»÷ÕâÀï²é¿´ JSON
ÏìÓ¦µÄʾÀý¡£
ÔÚ°²×°¹ý³ÌÖУ¬ÎÒÃÇÒѾ½« axios °üº¬ÔÚÎÒÃǵÄÓ¦ÓóÌÐòÖС£ÎÒÃÇÀ´¿´¿´
import
Vue from 'vue';
import axios from 'axios';
import App from './App';
if (!process.env.IS_WEB) Vue.use(require('vue-electron'));
Vue.http = Vue.prototype.$http = axios;
Vue.config.productionTip = false; |
Òò´Ë£¬ÎÒÃÇ¿ÉÒÔÔÚ×é¼þʵÀýÖÐ°Ñ axios ·½Ê½ÓÃ×÷ this.$http¡£ÔÚÕâÀÎÒÃǽ«Ö»ÎªÎÒÃǵÄ
API µ÷ÓÃÌí¼ÓÒ»¸ö»ù±¾ URL£º
axios.defaults.baseURL
= 'http://api.openweathermap.org/data/2.5'; |
ÏÖÔÚ£¬ÔÚ App.vue ÖУ¬ÎÒÃǽ«´´½¨Ò»×éÊý¾ÝÊôÐÔÀ´ÏÔʾ²»Í¬µÄÌìÆøÊý¾Ý£º
data()
{
return {
query: '',
error: false,
city: '',
country: '',
weatherDescription: '',
temp: null,
tempMin: null,
tempMax: null,
humidity: null,
icon: '',
};
}, |
Óë Vuido °æ±¾Ïà±È£¬ÎÒÌí¼ÓÁËÒ»¸ö¶îÍâÊôÐÔ£¬ËüÊǸöͼ±ê¡£API ÌṩÌìÆøÍ¼±ê£¬µ«ÊÇÎÒÃÇÎÞ·¨ÔÚ Vuido
Ó¦ÓóÌÐòÖÐʹÓã¬ÒòΪĿǰ²»Ö§³ÖÏÔʾͼÏñ¡£
ÎÒÃÇ»¹´´½¨ÁËÒ»ÖÖ·½·¨À´»ñÈ¡Êý¾Ý£º
methods:
{
showWeather() {
this.$http
.get(`/weather?q=${this.query}&units=metric&&appid=${API_KEY}`)
.then(response => {
this.city = response.data.name;
this.country = response.data.sys.country;
this.weatherDescription = response.data.weather[0].description;
this.temp = response.data.main.temp;
this.tempMin = response.data.main.temp_min;
this.tempMax = response.data.main.temp_max;
this.humidity = response.data.main.humidity;
this.icon = `http://openweathermap.org/img/w/${
response.data.weather[0].icon
}.png`;
this.error = false;
})
.catch(() => {
this.error = true;
this.city = '';
});
},
}, |
²¢°ÑËüÌí¼Óµ½°´Å¥µÄµ¥»÷»Øµ÷ÖУº
<button
:disabled="!query.length" @click="showWeather">Check</button> |
ÏÖÔÚ£¬Èç¹ûÔÚÊäÈë×Ö¶ÎÊäÈëÎı¾£¬µ¥»÷°´Å¥£¬¾Í¿ÉÒÔÔÚ¡°ÍøÂ磨Network£©¡± Ñ¡ÏÉϹ۲ì API µ÷Óãº

ÏÔʾÌìÆøÊý¾Ý
ÎÒÃǰÑÕâЩÊý¾ÝÌí¼Óµ½Ä£°åÉÏ£º
<template>
<main id="app">
<p>Enter the city name to check current
weather in it</p>
<section class="weather-input">
<input type="text" v-model="query">
<button :disabled="!query.length"
@click="showWeather">Check</button>
</section>
<section v-if="error" class="weather-error">
There is no such city in the database
</section>
<section v-if="city.length" class="weather-result">
<h1>{{city}}, {{country}}</h1>
<p><em>{{weatherDescription}}</em></p>
<div class="weather-result__main">
<img :src="icon" alt="Weather
icon">
<div class="weather-result__temp">
{{temp}}°C
</div>
</div>
<div class="weather-result__details">
<p>Min: {{tempMin}}°C</p>
<p>Max: {{tempMax}}°C</p>
<p>Humidity: {{humidity}}%</p>
</div>
</section>
</main>
</template> |
ÎÒÃǵÄÓ¦ÓóÌÐòÊÓͼ£º

Ì«°ôÁË£¬ÎÒÃÇÄÜ¿´µ½ÕæÊµµÄÌìÆø×´¿öÁË£¡µ«ÊÇ£¬Ëü¿´ÆðÀ´ÏñÊÇ 1999 ÄêµÄ¡¡ÎÒÃǸøËüÌí¼Óµã CSS
ħ·¨°É£¨ÊÂʵÉÏ£¬ÊǺܶà CSS ħ·¨£©£¡
<style
lang="scss">
* {
margin: 0;
padding: 0;
}
html,
body,
#app {
height: 100%;
}
#app {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
padding: 10px;
background: rgb(212, 228, 239);
background: -moz-radial-gradient(
center,
ellipse cover,
rgba(212, 228, 239, 1) 0%,
rgba(134, 174, 204, 1) 100%
);
background: -webkit-radial-gradient(
center,
ellipse cover,
rgba(212, 228, 239, 1) 0%,
rgba(134, 174, 204, 1) 100%
);
background: radial-gradient(
ellipse at center,
rgba(212, 228, 239, 1) 0%,
rgba(134, 174, 204, 1) 100%
);
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#d4e4ef', endColorstr='#86aecc',GradientType=1
); /* IE6-9 fallback on horizontal gradient
*/
}
.weather-input {
display: flex;
align-items: center;
padding: 20px 0;
}
.weather-result {
text-align: center;
&__main {
display: flex;
align-items: center;
justify-content: center;
padding-top: 5px;
font-size: 1.3rem;
font-weight: bold;
}
&__details {
display: flex;
align-items: center;
justify-content: space-around;
color: dimgray;
}
}
.weather-error {
color: red;
font-weight: bold;
}
input {
width: 75%;
outline: none;
height: 20px;
font-size: 0.8rem;
}
button {
display: block;
width: 25%;
height: 25px;
outline: none;
border-radius: 5px;
white-space: nowrap;
margin: 0 10px;
font-size: 0.8rem;
}
</style> |
×îÖÕ£¬ÎÒÃÇÓµÓÐÁËÕâ¸öÃÀÃîµÄÈ«¹¦ÄÜÓ¦ÓóÌÐò£º

ÔÚ´ò°ü֮ǰ£¬×îºóÒª×öµÄÊÂÊǰÑËüµÄ³ß´çËõСµ½´°¿Ú´óС¡£Èç¹ûÎÒÃDz鿴һÏ src/main/index.js
Îļþ£¬¿ÉÒÔÕÒµ½ËüµÄÉèÖÃÑ¡Ï
mainWindow
= new BrowserWindow({
height: 563,
useContentSize: true,
width: 1000
}) |
ÎÒÃǰѿí¶È¸ÄΪ 450£¬¸ß¶È¸ÄΪ 250¡£
´ò °ü
Äã¿ÉÒÔ°ÑÄãµÄÓ¦ÓóÌÐò¹¹½¨Îª web Ó¦ÓóÌÐòÁË£¡Èç¹ûÔËÐÐ build:web ÈÎÎñ£¬¿ÉÒÔÔÚ dist
Îļþ¼ÐÖÐÕÒµ½¹¹½¨ web Ó¦ÓóÌÐò¡£
µ«ÊÇ£¬ÈÃÎÒÃǻص½ÎÒÃǵÄ×ÀÃæÓ¦ÓóÌÐò²¢ÔËÐй¹½¨ÈÎÎñ¡£½á¹û£¬ÄãÔÚ¹¹½¨Îļþ¼ÐÖлáÓÐÒ»¸öÎļþ¼Ð£¬¸ÃÎļþ¼ÐµÄÃû×ÖÊǸù¾ÝÄãµÄƽ̨ÃüÃûµÄ£¨¶ÔÎÒ¶øÑÔÊÇ
mac£©£¬ÀïÃæÓÐÒ»¸öÓ¦ÓóÌÐòÎļþ¡£ËüµÄ´óСÊÇ 133Mb£¡

¶ÔÓÚÕâôСµÄÓ¦ÓóÌÐòÀ´Ëµ£¬ÕâÎļþÌ«´óÁË¡£ÁíÍ⣬Èç¹ûÔËÐÐһϣ¬Äã¾Í»á×¢Òâµ½£¬ËüµÄÆô¶¯±È Vuido
Ö§³ÖµÄÓ¦ÓóÌÐòÂý¡£
×îÖÕµÄÑù×Ó£º

½á ÂÛ
Óŵ㣺
1.ÈÝÒ×ÉÏÊÖ£»
2.³öÉ«µÄÎĵµ£»
3.Ìṩ web Ó¦ÓóÌÐò¹¹½¨£»
4.¿ÉÒÔͨ¹ý CSS Ñùʽ×Ô¶¨Òå¡£
ȱµã£º
1.´ò°üºóµÄÎļþ³¬´ó£»
2.±ÈÓñ¾»ú GUI ×é¼þ¹¹½¨µÄÓ¦ÓóÌÐòËÙ¶ÈÂý£»
3.Èç¹ûÄãµÄÓ¦ÓóÌÐòÐèÒª¶ÀÌØµÄÍâ¹Û£¬²¢ÇÒÄã²»ÔÚºõ£»
4.´ò°üºóµÄÎļþ´óСºÍÐÔÄÜ£¬ÄÇô£¬Electron-vue ÊǸö²»´íµÄÑ¡Ôñ¡£
¸üÐÂ
Èç¹ûÄãµÄ web Ó¦ÓóÌÐòÊÇÓà Vue CLI 3 ¹¹½¨µÄ£¬Ôò¿ÉÒÔÓà Vue CLI ²å¼þ Electron
Builder °ÑËü¼ò»¯³É×ÀÃæÓ¦ÓóÌÐò¡£ÄãÖ»ÐèÔÚÏîÄ¿¸ùÎļþ¼ÐÖÐÔËÐÐÒÔÏÂÃüÁ
ÔËÐнáÊøºó£¬Ä㽫»áÓµÓÐÁ½¸ö¶îÍâµÄ npm ÈÎÎñ£ºserve:electron ºÍ build:electron£¬Óë×ÀÃæÓ¦ÓóÌÐòÒ»Æð¹¤×÷¡£ |