传送门:天气预报APP - 微信小程序开发系列教程(上)
在上部教程中我们主要完善了util.js,通过 wx.request调用darksky及百度地图的相关API接口获取到了当前地址以及一周的天气数据,并把request结果通过module.exports相应函数暴露给应用层,那系列教程下,我主要要教会大家如何使用数据绑定以及建立视图结构,最终成型一个完整的APP。
先从app.js/app.json/app.wxss开始?
通过以前的教程我们知道:
app.json文件来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等
app.js主要定义App() 函数,用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。
app.wxss是项目样式定义文件,用于描述项目 WXML 的组件样式
首先app.json:
 | | {
 |  |   "pages":[
 |  |     "pages/index/index"
 |  |   ],
 |  |   "window":{
 |  |     "backgroundTextStyle":"dark", //深色样式,决定了导航、刷新等全局样式
 |  |     "navigationBarBackgroundColor": "#041028", //自定义导航背景颜色
 |  |     "navigationBarTitleText": "天气小程序", //初始显示导航名称
 |  |     "navigationBarTextStyle":"white" //文字设为白色
 |  |   }
 |  | } |  
  | 
app.js:
 | | //app.js
 |  | //app.js比较简单,我们就使用如下代码来初始化
 |  | App({
 |  |   onLaunch: function () {
 |  |   }, 
 |  |   globalData:{
 |  |     userInfo:null
 |  |   }
 |  | }) |  
  | 
app.wxss的代码我们一会再说,随着项目wxml一起列出来!
那,通过app.json我们知道一共就定义了1个页面,同时我们还知道pages数组的第一项代表小程序的初始页面,那我们找到pages/index/index目录,如果没有可以自行修改pages路径或者新建对应文件夹以及文件。
项目数据初始化
微信小程序的一个规定:页面文件名不需要写文件后缀,因为框架会自动去寻找页面路径对应.json,.js,.wxml,.wxss的四个文件进行整合。
所以我们第一步,解决如何把上节课说到的数据给load进来并进行数据初始化,从而给wxml结构模板数据绑定并渲染,打开index.js,首先就是要require上节课写好的util.js工具脚本。我直接上代码,再逐个注释下重点:
| 1 |  | 2 |  | 3 |  | 4 |  | 5 |  | 6 |  | 7 |  | 8 |  | 9 |  | 10 |  | 11 |  | 12 |  | 13 |  | 14 |  | 15 |  | 16 |  | 17 |  | 18 |  | 19 |  | 20 |  | 21 |  | 22 |  | 23 |  | 24 |  | 25 |  | 26 |  | 27 |  
  | | //index.js
 |  | //获取应用工具脚本
 |  | var util = require('../../utils/util.js')
 |  |  
 |  | Page({
 |  |   data: {
 |  |     //先初始化定义weather为一个空值
 |  |     weather: {}
 |  |   },
 |  |   onLoad: function () {
 |  |     var that = this; //防止this混淆掉
 |  | 
 |  |     util.loadWeatherData(function(data){
 |  |       //###重点:将获取到的数据从逻辑层发送到视图层,同时改变对应的 this.data 的值
 |  |       that.setData({
 |  |         weather: data
 |  |       });
 |  | 
 |  |       //动态更新#导航栏#为『城市名称+天气预报』
 |  |       wx.setNavigationBarTitle({
 |  |         title: data.city + ' 天气预报'
 |  |       })
 |  | 
 |  |     });
 |  |     
 |  |   }
 |  | }) |  
  | 
通过console,我们打印出获取的数据结构是下图所展示的:

项目数据绑定
数据已经发送到了视图层,那我们需要下一步做的就是在视图层进行数据绑定,打开index.wxml,代码如下:
| 1 |  | 2 |  | 3 |  | 4 |  | 5 |  | 6 |  | 7 |  | 8 |  | 9 |  | 10 |  | 11 |  | 12 |  | 13 |  | 14 |  | 15 |  | 16 |  | 17 |  | 18 |  | 19 |  | 20 |  | 21 |  | 22 |  
  | | <!--index.wxml-->
 |  | <view class="container">  
 |  |   <view class="top">
 |  |     <view>{{weather.city}}</view>
 |  |     <view>{{weather.current.formattedDate}}</view>
 |  |     <view id="update_time">{{weather.current.formattedTime}} 更新</view>
 |  |   </view>
 |  |   <view class="topRegion">
 |  |     <view id="temperature" >{{weather.current.temperature}}℃</view>
 |  |     <view id="summary" >{{weather.current.summary}}</view>
 |  |   </view>
 |  |   <view class="summary" >
 |  |     <view>{{weather.daily.summary}}</view>
 |  |   </view>
 |  |   <view class="daily" >
 |  |     <view class="daily_item" wx:for="{{weather.daily.data}}">
 |  |       <view class="daily_weekday" >{{item.weekday}}</view>
 |  |       <view class="daily_temperature" >{{item.temperatureMin}}-{{item.temperatureMax}}℃ </view>      
 |  |       <view class="daily_summary" >{{item.summary}}</view>
 |  |     </view>
 |  |   </view>
 |  | </view> |  
  | 
如果按照我教程步骤,保存完你应该会看到:

我们已经把主要内容给展示了出来!PS: 其实index.wxml代码也非常简单,数据绑定使用 Mustache 语法(双大括号)将变量包起来,如{{data.xxx}},具体使用可以参考:微信小程序官方教程之数据绑定,或者去看看Vue.js(版本随意,链接自行Google)文档也是没错的。
项目样式优化
如果你的app就如上图所展示的,我敢打赌,不会有任何人喜欢,因为它太简陋,太不易查看。所以你必须为你的程序换上一件漂亮的衣服,让它变得简约又易用,这是我们一直追求的目标!同之前的代码一样,我们也是直接上样式代码,因为和css大部分兼容,所以理解起来非常容易。
对了,我们的样式没有写在pages/index/index.wxss,而是写在了app.wxss,其实都可以,展现上没有任何不同,严格意义上来说,我应该把全局共用的样式放在app.wxss里面,把页面单独的组件样式放在各自的.wxss内,但是由于我们此次开发的天气APP只包含一个页面,所以,无论你放在哪都可以,都不会造成太大的困扰,毕竟就一个页面而已:)
明白了我们就直接上代码,可以看到大部分都是css语法,没有特别需要说明的:
| 1 |  | 2 |  | 3 |  | 4 |  | 5 |  | 6 |  | 7 |  | 8 |  | 9 |  | 10 |  | 11 |  | 12 |  | 13 |  | 14 |  | 15 |  | 16 |  | 17 |  | 18 |  | 19 |  | 20 |  | 21 |  | 22 |  | 23 |  | 24 |  | 25 |  | 26 |  | 27 |  | 28 |  | 29 |  | 30 |  | 31 |  | 32 |  | 33 |  | 34 |  | 35 |  | 36 |  | 37 |  | 38 |  | 39 |  | 40 |  | 41 |  | 42 |  | 43 |  | 44 |  | 45 |  | 46 |  | 47 |  | 48 |  | 49 |  | 50 |  | 51 |  | 52 |  | 53 |  | 54 |  | 55 |  | 56 |  | 57 |  | 58 |  | 59 |  | 60 |  | 61 |  | 62 |  | 63 |  | 64 |  | 65 |  | 66 |  | 67 |  | 68 |  | 69 |  | 70 |  | 71 |  | 72 |  | 73 |  | 74 |  | 75 |  | 76 |  | 77 |  | 78 |  | 79 |  | 80 |  | 81 |  | 82 |  | 83 |  | 84 |  | 85 |  | 86 |  | 87 |  | 88 |  | 89 |  | 90 |  | 91 |  | 92 |  | 93 |  | 94 |  | 95 |  | 96 |  | 97 |  | 98 |  | 99 |  | 100 |  | 101 |  | 102 |  | 103 |  | 104 |  | 105 |  | 106 |  | 107 |  | 108 |  | 109 |  | 110 |  | 111 |  | 112 |  | 113 |  
  | | /**app.wxss**/
 |  | page{
 |  |   font-family: "PingFang SC","STHeitiSC-Light","Helvetica Neue","Helvetica","Arial",sans-serif;
 |  |   font-weight: 100;
 |  |   background: #041028 url(../../images/weather.jpg) center bottom no-repeat;
 |  |   background-size: 100%;
 |  | }
 |  | .container {
 |  |   height: 100%;
 |  |   display: flex;
 |  |   flex-direction: column;
 |  |   box-sizing: border-box;
 |  |   background-size: 100%;
 |  |   padding: 20rpx;
 |  | } 
 |  | 
 |  | .top {
 |  |   flex-direction: row;
 |  |   margin-top: 40rpx;
 |  | }
 |  | 
 |  | .top view {
 |  |   color: #fff;
 |  |   text-align: right;
 |  |   font-size: 30rpx;
 |  |   margin-bottom: 10rpx;
 |  | }
 |  | 
 |  | .topRegion {
 |  |   padding-top: 100rpx;
 |  |   height:100rpx;
 |  |   vertical-align: bottom;
 |  | }
 |  | 
 |  | .topRegion #temperature {
 |  |   color:#fff;
 |  |   float: left;
 |  |   font-size: 120rpx;
 |  |   font-weight: 600;
 |  | }
 |  | 
 |  | .topRegion #summary {
 |  | 
 |  |   color:#FFF;
 |  |   margin-left: 30rpx;
 |  |   margin-top: 70rpx;
 |  |   font-size: 50rpx;
 |  |   float: left;    
 |  | 
 |  | }
 |  | 
 |  | #update_time{
 |  |   font-size: 20rpx;
 |  |   padding-top:20rpx;
 |  | }
 |  | .topRegion text {
 |  |   display: block;
 |  |   float: left;
 |  |   width: 250rpx;
 |  |   text-align: center;  
 |  | }
 |  | 
 |  | .summary {
 |  |   padding: 62rpx 18rpx 18rpx;
 |  |   color: #eee;
 |  |   font-size: 24rpx;
 |  |   line-height: 50rpx;
 |  | 
 |  | }
 |  | 
 |  | .daily {
 |  |   position: fixed;
 |  |   bottom:0;
 |  |   left: -20rpx;
 |  |   padding: 20rpx 52rpx;
 |  |   background-color:rgba(0, 0, 0, 0.6);
 |  | }
 |  | 
 |  | .daily_item {
 |  | 
 |  |   float:left;
 |  |   width:100%;
 |  |   color: #FFF;  
 |  |   height:80rpx;
 |  |   padding-left: 20rpx;
 |  |   line-height: 80rpx;
 |  |   font-size: 24rpx;
 |  | 
 |  | }
 |  | 
 |  | .daily_weekday {
 |  |   
 |  |   display: block;
 |  |   float: left;     
 |  |   width: 60rpx;
 |  | }
 |  | 
 |  | .daily_temperature {
 |  |   
 |  |   float: left;
 |  |   display: block;  
 |  |   width: 120rpx;
 |  |   margin-right: 50rpx;
 |  |   text-align: right;
 |  | 
 |  | }
 |  | 
 |  | .daily_summary {
 |  |   
 |  |   float: left;
 |  |   display: block;  
 |  | 
 |  | } |  
  | 
如果非得有需要注意的就是flex的使用以及尽快熟悉rpx:

源码下载
下载源码压缩包
写在最后
至此,我们用了两篇文章跟大家介绍了一个天气小程序从构建到开发的完整过过程。 这个天气小程序逻辑并不复杂,但通过它大家应该可以对整个开发的过程有一个亲身的了解。目前我们APP当然离好用还有一段距离,这些优化希望你们能举一反三的去尝试,有任何问题和我留言,很高兴与你们一起共同探讨学习。
    
[...]欲知后事如何?传送门:天气预报APP - 微信小程序开发系列教程(下)[...]
https://api.darksky.net 不在以下 request 合法域名列表中,请参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html
现在这个api域名被禁止了,哭死
逻辑清晰 照着做我也搞出来啦,哈哈哈哈哈哈哈 小有成就