天天看點

微信小程式開發實戰-天氣小程式

從0開始一步步建立一個天氣預報的微信小程式

園齡6年8個月了,還一篇文章都沒寫過,慚愧!

最近周末做了個天氣預報小程式,在這裡整理一下開發過程和注意點,給對小程式開發感興趣的夥伴們提供點參考。

廢話不多說,先上圖最終效果:

微信小程式開發實戰-天氣小程式

下面進入正文:

第一步  準備

0. 把微信小程式開發文檔過一遍。https://developers.weixin.qq.com/miniprogram/dev/framework/  作為程式員,就要從0開始計數。

1. 下載下傳安裝微信開發者工具(https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html),這個就不多說了。

2. 設計産品原型,我們要把産品做成什麼樣。

先曬一下第一版的原型,比較醜,見諒。(第一版醜和簡陋先忍,後面可以疊代)

下面的代碼也會是第一版,功能沒有上面掃碼看到的那麼多。我是希望能從0開始寫起,然後把每次疊代也寫上,讓大家能看到一個項目是怎麼從第一版最簡陋的功能,逐漸功能豐富和完善。這才是一個項目真正的開發過程。一開始就做的很複雜很完備的,往往容易難産。

微信小程式開發實戰-天氣小程式

 然後我們接口需要向頁面提供的資訊就明确了:位置名、實時溫度、天氣文字、空氣文字、今日日期、今日天氣狀況。

第二步 啟程 開發小程式前端頁面

【10點20了,終于下班到家,有時間繼續補充了】

0.建立項目

打開微信開發者工具,建立一個新項目。暫起名“miniweather”(名字不重要,以後可以随時改)。如下圖:

微信小程式開發實戰-天氣小程式

建立完成後,預設微信開發者工具就把項目編譯預覽出來了,效果如下。

微信小程式開發實戰-天氣小程式

點選“擷取頭像昵稱按鈕”,界面變成如下:

微信小程式開發實戰-天氣小程式

(請忽略我吊炸天的微信名)

1. 編寫頁面内容

由于咱們這個天氣預報隻有一個頁面,就直接在index這個頁面改起,沒必要建立新頁面了。

删掉index.wxml中的全部代碼,稍後重寫。

删掉index.wxss中的全部樣式代碼,稍後重寫。

咱們從頭寫起。如果你熟悉html和css,那麼這個wxml和wxss就很容易上手了。

先貼代碼如下

index.wxml:

1 <view class="weather-wrapper">
 2   <view class="location-text">北京</view>
 3   <view class="temp">30°</view>
 4   <view class="weather">
 5     <text class="weather_txt">晴</text>
 6     <text class="air_label">空氣優</text>
 7   </view>
 8   <view class="day-weather">
 9     <view class="day-text">2019-09-12</view>
10     <view class="temp-text">晴轉多雲</view>
11   </view>
12 </view>      

上面wxml( 相當于web開發的html )就這麼12行。把頁面需要的元素列出來,并加了對應的class名,稍後我們可以針對class設定樣式。

現在的效果是這樣的:

微信小程式開發實戰-天氣小程式

頁面沒有任何樣式,但是基本内容都有了。

接下來,編輯index.wxss檔案(wxss相當于web開發的css),把樣式加上。

仍然是先貼代碼:

index.wxss

1 .weather-wrapper{
 2   position: relative;
 3   padding-top: 20rpx;
 4   padding-bottom: 250rpx;
 5 }
 6 .location-text{
 7   text-align: center;
 8 }
 9 .temp {
10   text-align:center;
11   font-size:200rpx;
12   line-height:280rpx;
13   opacity:0.8;
14 }
15 .weather {
16   text-align: center;
17   font-size: 40rpx;
18   line-height: 56rpx;
19   opacity: 0.65;
20 }
21 .air_label{
22   margin-left: 20rpx;
23   border-radius: 10rpx;
24   padding:8rpx;
25 }
26 .day-weather {
27   display: flex;
28   align-items: center;
29   position: absolute;
30   bottom:0;
31   left: 40rpx;
32   right: 40rpx;
33   height: 90rpx;
34   font-size: 30rpx;
35   line-height: 42rpx;
36   color: rgba(0, 0, 0, 0.5)
37 }
38 .temp-text {
39   flex-grow: 1;
40   padding-right: 30rpx;
41   text-align: right;
42 }      

 儲存index.wxss檔案,工具自動編譯,這下再看預覽效果,順眼多了

微信小程式開發實戰-天氣小程式

2. 加背景圖

頁面架構有了,但是還沒有圖檔資源,顯得很簡陋,這一步我們給它加一個背景圖。

首先建立一個images/background目錄,然後把背景圖檔存到backgrond目錄中。

之後,修改index.wxml檔案,在weather-wrapper類中加入圖檔:

<image src="/images/background/sunny.png" mode="scaleToFill" class="bgimg"></image>      

mode="scaleToFill"表示将圖檔拉伸填滿,可以檢視圖檔的官方文檔了解詳情。

class="bgimg"  是我們給圖檔定義一個叫bgimg的類,友善稍後我們給它設定樣式。

之後我們的index.wxml變成如下:

<view class="weather-wrapper">
  <image src="/images/background/sunny.png" mode="scaleToFill" class="bgimg"></image>
  <view class="location-text">北京</view>
  <view class="temp">30°</view>
  <view class="weather">
    <text class="weather_txt">晴</text>
    <text class="air_label">空氣優</text>
  </view>
  <view class="day-weather">
    <view class="day-text">2019-09-12</view>
    <view class="temp-text">晴轉多雲</view>
  </view>
</view>      

再編輯index.wxss,給bgimg設定樣式。添加代碼如下:

.bgimg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}      

之後,我們的index.wxss變成如下:

.weather-wrapper {
  position: relative;
  padding-top: 20rpx;
  padding-bottom: 350rpx;
}
.bgimg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}
.location-text {
  margin-top: 50rpx;
  text-align: center;
}
.temp {
  text-align: center;
  font-size: 200rpx;
  line-height: 280rpx;
  opacity: 0.8;
}
.weather {
  text-align: center;
  font-size: 40rpx;
  line-height: 56rpx;
  opacity: 0.65;
}
.air_label {
  margin-left: 20rpx;
  border-radius: 10rpx;
  padding: 8rpx;
}
.day-weather {
  display: flex;
  align-items: center;
  position: absolute;
  bottom: 0;
  left: 40rpx;
  right: 40rpx;
  height: 90rpx;
  font-size: 30rpx;
  line-height: 42rpx;
  color: rgba(0, 0, 0, 0.5);
}
.temp-text {
  flex-grow: 1;
  padding-right: 30rpx;
  text-align: right;
}      

儲存檔案,點選“編譯”按鈕,檢視效果

微信小程式開發實戰-天氣小程式

 有了背景圖,看起來美觀多了。

【下方的白色空白是特意預留的,以後展示未來天氣的預報資訊,這部分此篇文章篇幅所限就不寫了】

第三步  找資料源 提供資料接口

這一步可走的路就多了。

有專門提供天氣api接口的廠商,免費、收費都有。比如墨迹、彩雲、和風等專門就是幹這個的

也可以自己寫代碼去爬資料。

這裡為了學習,可以先用和風天氣的免費接口,去上面注冊一個賬号,然後看官方文檔,了解怎麼擷取到天氣資訊。

其實正規項目,我們應該有自己的後端服務,後端自己制造、存儲資料或者和第三方(如和風天氣)互動擷取資料,自己的小程式隻向自己的後端接口請求資料。不過這東西攤開來講就太多了,它是一整個技術棧,涉及了太多方面。

我是建構了自己的後端服務,但是對于初學者,我沒法在這裡指導你們從頭開始建構。(想想需要買雲主機、買域名、域名備案、進行環境配置、寫後端服務代碼、代碼上線部署等,一大攤子事,不是三言兩語或者幾篇文章能寫清楚的)

至于小程式力推的雲開發,我個人其實不推薦。雲開發雖然友善了開發者,省去買伺服器、域名、資料庫等各種事,看似對開發者友好,但事情都有兩面性。雲開發塑造了一個封閉的生态圈,所有東西都在微信的統轄内,不利于網際網路的開放,如果想把資料給網站、app使用也很難。而且當使用者量大的時候,雲開發并不會節省多少成本。

是以接下來就讓小程式直接調用和風天氣的接口來擷取資料作為示範。

第四步 小程式通過接口調資料,展示資訊

0.移除無用代碼

對于資料的的操作,我們在index.js中進行。預設的index.js中太多無用的東西了,天氣小程式不需要擷取使用者資訊,是以不想關的都删掉,最終index.js内容如下:

Page({
  data: {
  },
  onLoad: function () {
  }
})      

1.設定頁面從js中擷取初始資料

其中data是用來存放頁面初始資料的,我們可以在裡面設定初始資料,傳遞給頁面。

修改後index.js内容如下:

Page({
  data: {
    location_text:\'北京\',
    temperature:\'30°\',
    now_weather: \'晴\',
    now_air: \'優\',
    today:\'2019-09-12\',
    today_weather: \'晴轉多雲\'
  },
  onLoad: function () {
  }
})      

 然後修改index.wxml,接收這些參數,修改完的index.wxml如下:

<view class="weather-wrapper">
  <image src="/images/background/sunny.png" mode="scaleToFill" class="bgimg"></image>
  <view class="location-text">{{location_text}}</view>
  <view class="temp">{{temperature}}</view>
  <view class="weather">
    <text class="weather_txt">{{now_weather}}</text>
    <text class="air_label">空氣{{now_air}}</text>
  </view>
  <view class="day-weather">
    <view class="day-text">{{today}}</view>
    <view class="temp-text">{{today_weather}}</view>
  </view>
</view>      

儲存檔案,自動編譯,檢視效果:

微信小程式開發實戰-天氣小程式

2. js擷取和風天氣資料,渲染到頁面

 前置工作:

登入和風天氣控制台,建立應用,生成了一個免費版的key來使用。後面調用天氣接口需要用到這個key

擷取位置資訊

要查詢當地天氣,需要先有位置資料,這個推薦使用騰訊位置服務。官方文檔寫的清清楚楚,直接用官方例子就行。

這個在小程式背景開通,也要擷取一個key。

微信小程式開發實戰-天氣小程式

擷取位置資訊需要使用者授權,需要把要擷取的授權資訊寫在app.json中。 

app.json增加如下代碼:

"permission": {
    "scope.userLocation": {
      "desc": "你的位置資訊将用于小程式擷取目前位置天氣"
    }
  },      

利用位置資訊,調用和風天氣接口擷取天氣資料

請求網絡接口用 wx.request()方法   文檔

把資料渲染到頁面

使用setData({})方法,把初始值換成我們從接口擷取到的真實值。

最終index.js内容如下:

const QQMapWX = require(\'../../utils/qqmap-wx-jssdk.js\')
Page({
  data: {
    location_text: \'北京\',
    temperature: \'30°\',
    now_weather: \'晴\',
    now_air: \'優\',
    today: \'2019-09-12\',
    today_weather: \'晴轉多雲\'
  },
  onLoad: function () {
    this.qqmapsdk = new QQMapWX({
      key: \'EAXBZ-33R3X-AA64F-7FIPQ-BY27J-5UF5B\'
    })
    this.getCityAndWeather()
  },
  // 擷取位置及天氣
  getCityAndWeather() {
    var that = this;
    wx.getLocation({
      success: res => {
        this.location_pin = res.longitude + \',\' + res.latitude
        this.qqmapsdk.reverseGeocoder({
          location: {
            latitude: res.latitude,
            longitude: res.longitude
          },
          success: res2 => {
            let city = res2.result.address_component.city
            that.setData({
              location_text: city,
            })
            that.getNowWeather()
          }
        })
      },
      fail: () => {
        console.log(\'未授權位置\');
      }
    })
  },

  // 擷取目前天氣
  getNowWeather() {
    let that = this
    let hfkey = \'3b820c451ee144629f959b464b2dd6a5\'
    let url = \'https://free-api.heweather.net/s6/weather/now?key=\' + hfkey + \'&location=\' + this.location_pin

    wx.request({
      url: url,
      success: function (res) {
        console.log(\'success\')
        console.log(res)
        let nowData = res.data.HeWeather6[0].now;
        //溫度資料
        let temperature = nowData.tmp
        //目前天氣文字描述
        let now_weather = nowData.cond_txt
        // 今日日期
        var date = new Date()
        const year = date.getFullYear()
        const month = date.getMonth() + 1
        const day = date.getDate()
        that.setData({
          temperature: temperature + \'°\',
          now_weather: now_weather,
          today: year + \'-\' + month + \'-\' + day
        })
      },
      fail: function (res) {
        console.log()
      }
    })
  }
})      

上面隻調用了一個接口擷取資料,要擷取頁面其它資料,還需要調用其它接口,方法大同小異,我這裡就不重複寫了。可以參考上面的代碼自行實作。

可能遇到的問題及解決辦法:

1.提示域名不合法:可以取消對域名的校驗(開發工具中 詳情->本地設定->勾選不校驗合法域名...),或者在公衆平台小程式背景把域名資訊加進去。

本文完整代碼下載下傳

完整代碼包: 下載下傳位址