zoukankan      html  css  js  c++  java
  • 微信小程序,天气预报(百度地图开放平台API)

    小程序看似一种全新的东西,但好在基本上就是曾经HTML,CSS,JS的一个微变版本。

    语法和之前一样。只是一些用法和名字(标签)发生了一些变化。

    小程序主要就四种扩展名的文件:js,json,wxml,wxss

    JS,小程序的功能实现文件,和普通的JavaScript没什么区别,更多的是加入了一些微信扩展的方法,可以与微信进行一些交互。

    JSON,小程序的配置文件,也比较简单,格式和之前熟知的JSON文本文件没有区别,在小程序里主要也是用于配置环境和属性等。

    WXSS,小程序的样式文件,语法和普通的CSS没啥区别,直接上手就用即可。

    WXML,这个语法上和HTML没区别,也是标签类语言,只是标签名字有变化,同时不像HTML标签只是含义不同,默认样式不同,是真正具备一定的功能的。

    所以,小程序理论上,了解了WXML标签读含义和功能,了解了微信提供的哪些接口交互。再了解一下小程序的机制,基本上就算是会小程序了。

    这里,用微信小程序和百度地图提供的天气接口,来简单说一说,如何做一款自己的简单的微信小程序

    一、准备工作

      账号申请

      ※ 微信公众平台的账号申请:https://mp.weixin.qq.com/

      ※ 百度地图开放平台帐号申请:http://lbsyun.baidu.com/

      开发微信小程序,是必须要在微信公众帐号平台注册的,并找到AppID(小程序ID),这个是核心所有小程序开发都要有。

      这个是关键的东西,小程序需要在微信提供的“微信web开发者工具”,这个工具需要微信登录,所有小程序项目开发必须要输入AppID。

      微信公众平台帐号申请完成之后,登录。

      左菜单【开发->开发设置】中,就可以看到AppID,是一串类似于乱码的字符串。类似这样:wx123abc456bcd789cde

      在微信开发工具中,需要的地方,填入这个AppID即可。

      百度地图开放平台申请帐号的目的是为了获取一个访问应用(AK),这个AK是关键,任何调用百度地图相关接口时需要使用这个AK初始化接口。

      进入控制台,应用列表里,就可以根据页面的提示,自行操作,创建一个或者多个AK,不同项目申请不同的AK。

      这两部分准备工作做好之后,就可以正式开始开发小程序了。

    二、第一个小程序

      这个不需要做什么操作,只要打开“微信web开发者工具”,创建一个小程序项目,就会得到一个最基本的小程序项目

      直接编译就可以通过模拟器部分看到一个hello world的小程序

      自行调试,测试,看看这第一个程序源码即可。当然最基本的地方是非常简单的。代码有编程基础的人都能看懂。

      其中,只有获取当前微信信息的部分稍微绕了一点。尤其是那个莫名奇妙的“回调程序”。

      不过好在,短期内不理解,可以直接使用,随着日后逐渐开发反复调用,慢慢可以摸索。

    三、微信小程序(百度地图API)天气预报

      先说下大致的思路:

      主要是两部分:定位授权和天气数据获取

      在页面加载时,先验证当前是否有用户授权定位信息,如果没有,则提示,并引导用户授权定位信息。

      接下来,如果用户已经授权定位信息之后,则调用一些列天气相关的接口,获取相应的数据,部分数据或许需要二次处理,然后保存到当前功能文件的data中。

      页面渲染时,会根据data中的值,或显示显示,或隐藏标签,或者显示具体的数据。

      

      开始说实例,首先,pages目录里的logs相关的都可以删除,app.json配置里的也同样,基本上和logs有关的这次都不需要,只保留index相关即可

      当然根目录下的不要删除。

      先说不是主要的部分

      1、配置文件xxx.json文件

    {
    "backgroundColor": "#bbb",
    "usingComponents": {},
    "enablePullDownRefresh": true,
    "navigationBarTitleText": "百度天气"
    }
    这个文件,主要就是配置页面的,具体需要什么,自己看微信提供的说明
     
    2、模板文件xxx.wxml
    <loading hidden="{{loadingStatus}}">
        加载中...
    </loading>
    <view wx:if="{{userLocation == 3}}" class="box weather_bg list_left">
      <text class='tips' bindtap='refreshCurrentPage'>
      定位异常,无法正确获取您的定位信息
    
      1.请重新刷新页面
    
      2.尝试换个地方重新刷新页面
    
      3.晚些时候再刷新页面
    
      4.非中国境内,无法正确获取
    
      5.如果上述操作依然存在问题,请联系作者
      </text>
    </view>
    <view wx:if="{{userLocation == 2}}" class="box city_title list_center">
      <text class='tips' bindtap='refreshCurrentPage'>
      没有授权获取定位信息,功能无法使用
    
      确认授权后,请下拉或者点击文字刷新获取数据
      </text>
      <button class='btn' bindtap='gotoAuthPage'>点击开启授权</button>
    </view>
    <view wx:elif="{{userLocation == 1}}">
      <view class="box city_title">
        <view class="city">{{cityInfo.addressComponent.city}}</view>
        <view class="pos">( {{cityInfo.location.lat}} , {{cityInfo.location.lng}} )</view>
      </view>
      <view class="box city_info">
        <view>地址:{{cityInfo.formatted_address}}</view>
        <view>邮编:{{cityInfo.addressComponent.adcode}}</view>
        <view>周边:{{cityInfo.business}}</view>
      </view>
      <view class='box weather_title'>天气情况</view>
      <view class="box weather_info">
        <view class='f_red'>{{weatherInfo.date}}</view>
        <view>
          <text class='f_black'>{{weatherInfo.weatherDesc}}</text>
          <text class='ml20'>{{weatherInfo.temperature}}</text>
          <text class='ml20'>{{weatherInfo.wind}}</text>
        </view>
        <view>PM2.5:{{weatherInfo.pm25}}</view>
      </view>
      <block wx:for="{{weatherInfoExt}}" wx:key="index">
        <block wx:if="{{index > 0}}">
          <view class="box weather_info">
            <image wx:if="{{currentTime >= '06' && currentTime < '18'}}" src='{{item.dayPictureUrl}}' mode="aspectFill" class='pic'></image>
            <image wx:else src='{{item.nightPictureUrl}}' mode="aspectFill" class='pic'></image>
            <text class='ml20'>{{item.date}}</text>
            <text class='ml20'>{{item.temperature}}</text>
            <text class='ml20'>{{item.weather}}</text>
            <text class='ml20'>{{item.wind}}</text>
          </view>
        </block>
      </block>
    </view>

    这个模板文件,主要分成四个部分:加载浮层、定位异常提示、未授权提示、正常天气预报展示

    简单说明:

    loading标签,效果是一个特效,一个“loading...”的浮层浮在手机页面上,数据和页面加载完成之后,可以控制其隐藏

    wx:if="{{userLocation == 3}}"相关标签,这个部分是当获取定位信息失败,或者超出接口范围时,显示提示信息

    wx:if="{{userLocation == 2}}"相关标签,这个部分是当前用户没有授权定位信息,展示的提示信息,并提供授权引导按钮

    剩下的标签代码,就是正常的天气信息显示的部分。

    页面上所有用{{}}这种双大括号括起来的都是变量标签,用于获取变量信息的,例如:{{userLocation == 2}}读出变量usesrLocation的值和2比较大小

    这些变量的值,都来自于xxx.js文件的Page->data里边定义的变量。

    3、样式文件xxx.wxss

    page{
      padding:0;
      background: #fdfdfd;
    }
    view{
      font-size: 32rpx;
      color: #333;
      font-family: "微软雅黑";
    }
    image{
      text-align: center;
      vertical-align:middle;
    }
    /* 通用部分 */
    .box{
      margin: 24rpx;
      padding: 24rpx;
      line-height: 180%;
    }
    .box_bg {
       background: #f0f6fa;
    }
    .list_left{
      text-align: left;
      line-height: 100%;
      padding-left: 40rpx;
    }
    .list_center{
      text-align: center;
      line-height: 100%;
      padding: 0;
    }
    /* 城市信息部分 */
    .city_title{
      align-items: center;
      display: flex;
      flex-direction: column;
      margin: -8rpx 0 -20rpx 0;
      padding-bottom: 0;
    }
    .city_title .btn{
      margin-top: 30rpx;
      font-size: 28rpx;
      color: #000;
    }
    .city_title .city{
      font-size: 36rpx;
      color: #000;
    }
    .city_title .pos{
      font-size: 32rpx;
    }
    .city_info{
      border: 1px solid #efefef;
    }
    /* 天气信息部分 */
    .weather_title{
      margin-bottom: -16rpx;
      padding-bottom: 0;
    }
    .weather_info{
      color: #555;
      border: 1px solid #efefef;
    }
    .weather_info .pic{
      padding: 0;
      margin:-4px 0 0 0;
      width:22px;
      height:16px
    }
    .weather_info .f_red{
      color: red;
    }
    .weather_info .f_black{
      color:black;
    }
    .weather_info .ml20{
      margin-left: 20rpx;
    }
    这些样式的写法,都是正常的CSS的写法,使用规则和CSS没有任何区别,就不做说明了。
     
    4、功能文件xxx.js
    // 获取全局app.js中的内容
    const app = getApp();
    // 引用工具文件
    var util = require('../../utils/util.js');
    // 引用百度地图提供的接口JS文件
    var bmap = require('../../utils/bmap-wx.min.js');
    
    Page({
      // 数据初始化
      data: {
        loadingStatus: false,
        userLocation: 0, // 0默认没有状态,1获取到用户定位,2用户拒绝提供定位信息,3无法获取正确定位
        cityInfo: {}, //城市信息
        weatherInfo: {}, //天气信息
        weatherInfoExt: {}, //天气扩展信息
        currentTime:'' // 当前时间
      },
    
      // 更新用户的位置获取的状态
      updateUserLocation: function (v) {
        this.setData({
          loadingStatus: true,// 加载完成,隐藏加载动画
          userLocation: v //更新当前页面的变量值
        });
      },
    
      // 跳转到授权页面
      gotoAuthPage: function(){
        wx.openSetting({
          fail: function () {
            wx.showModal({
              title: '操作失败',
              content: '请到微信中自行设置授权操作',
              confirmText: '知道了',
              confirmColor: '#345391',
              showCancel: false
            })
          }
        });
      },
    
      // 刷新当前页面(相当于下拉刷新页面)
      refreshCurrentPage: function(){
        wx.startPullDownRefresh({});
      },
    
      // 获取地理位置和天气的方法
      getLocationAndWeather: function () {
        var that = this;
        // 使用百度地图提供的ak标记,初始化地图数据
        var BMap = new bmap.BMapWX({
          ak: app.globalData.bmap_ak
        });
        // 失败执行的方法
        var fail = function (data) {
          if (data.errMsg == 'getLocation:fail auth deny') {
            // 更新页面状态为2,用户拒绝提供位置信息
            that.updateUserLocation(2);
          }else{
            // 更新页面状态为3,获取定位信息错误,或者定位不在大陆境内
            that.updateUserLocation(3);
          }
        };
        // 获取城市信息成功执行的方法
        var regeocoding_success = function (data) {
          // 获取地址数据
          var city_info = data.originalData.result;
          // 二次处理数据,将经纬度的数据,保留四舍五入保留五位小数
          city_info.location.lat = city_info.location.lat.toFixed(5);
          city_info.location.lng = city_info.location.lng.toFixed(5);
          // 更新页面状态为1,用户允许授权定位信息
          that.updateUserLocation(1);
          // 将相关数据,写到初始化的data数据中
          that.setData({
            cityInfo: city_info
          });
        };
        // 获取天气成功执行的方法
        var weather_success = function (data) {
          // 获取天气基本数据
          var weatherInfo = data.currentWeather[0];
          // 获取天气扩展信息
          var weatherInfoExt = data.originalData.results[0].weather_data;
          // 将天气预报数据写入定义(初始化)的变量中
          that.setData({
            weatherInfo: weatherInfo,
            weatherInfoExt: weatherInfoExt
          });
          // 天气获取成功之后,再调用其他数据(regeocoding接口有BUG,没有数据依然返回成功状态)
          // 调用接口获取城市地区信息
          BMap.regeocoding({
            fail: fail,
            success: regeocoding_success
          });
        };
        // 调用接口获取天气信息
        BMap.weather({
          fail: fail,
          success: weather_success
        });
      },
    
      // 加载执行
      onLoad: function () {
        app.checkUserLocation();
        // 获取当前时间,并拆分成日期和时间两部分
        var current_time = util.formatTime(new Date()).split(' ');
        // 将时间部分记录,用于判断早晚
        this.setData({
          currentTime: current_time[1]
        });
        // 调用获取天气和地理位置的方法
        this.getLocationAndWeather();
      },
    
      // 下拉页面执行页面刷新
      onPullDownRefresh: function () {
        wx.showNavigationBarLoading(); // 显示顶部刷新图标
        this.getLocationAndWeather(); // 调用获取天气和地理位置的方法
        wx.hideNavigationBarLoading(); // 隐藏导航栏加载框
        wx.stopPullDownRefresh(); // 停止下拉动作
      }
      
    })

    基本上所有的功能都是在js文件中完成的。

    简单说明:

    const app = getApp(); 这个定义,就是可以通过app这个常量,可以调用app.js文件中的变量和方法。
    var util = require('../../utils/util.js'); 
    将utils目录里的util.js文件引入到当前页面,同时,可以通过util这个变量访问该文件声明开放的方法。此文件默认自带
    var bmap = require('../../utils/bmap-wx.min.js'); 将百度地图API的文件引入当前页面,同时可以使用bmap变量使用其对外声明的方法。此文件需要百度平台下载
    ak: app.globalData.bmap_ak 这个需要把自己的ak值(来自百度地图开放平台)放到这里,才可以正常使用。
     
    因为所有代码,几乎每一句话都有注释,所以就不做详细的说明了。
     
    注意:百度地图提供的接口 BMap.regeocoding 是有问题的,所以,先调用了那个weather接口,其返回成功之后,再调用regeocoding方法,否则在特定情况下(比如定位非国内等)会错误。
     
    附上app.js的代码,因为上边的js文件中有使用其中的方法,当然也可以都移植到xxx.js文件中。
    App({
      globalData: {
        userInfoAuth: 0,//0无状态,1用户已经授权用户信息,2用户拒绝授权用户信息
        // 用户信息
        userInfo: null,
        // 百度地图提供的AK串
        bmap_ak: '百度地图开放平台的AK值',
        // cur_city_id: '' // 用于记录城市ID,在切换城市时,将目标城市ID记录,需要时读取
      },
    
      // 监听初始化
      onLaunch: function () {
    
      },
    
      onShow: function () { },//监听显示(进入前台)
      onHide: function () { },//监听隐藏(进入后台:按home离开微信)
    
      // 设置所在地(城市)
      // setLocal: function (id, val) {
      //   wx.setStorageSync(id, val);//API:设置本地缓存,将数据存储在本地缓存中
      // },
    
      // 用户位置授权验证及操作
      checkUserLocation: function () {
        var that = this;
        // 获取授权信息
        wx.getSetting({
          success: function (res) {
            // 判断是否已经操作过授权操作
            if (res.authSetting.hasOwnProperty("scope.userLocation")) {
              if (res.authSetting["scope.userLocation"] == true) {
                // 已经授权位置信息,暂时无操作
              } else {
                // 没有授权位置信息,弹出选择框提示用户选择操作
                wx.showModal({
                  title: '信息授权',
                  content: '提示:位置授权暂未开启,无法获取相关信息',
                  confirmText: '开启授权', 
                  cancelText: '仍然拒绝',
                  // confirmColor: '#345391',
                  cancelColor: '#666',
                  success: function (res) {
                    if (res.confirm) {
                      // 用户选择“允许”,则开启授权页面
                      wx.openSetting({
                        fail: function () {
                          wx.showModal({
                            title: '操作失败',
                            content: '请到微信中自行设置授权操作',
                            confirmText: '知道了',
                            confirmColor: '#345391',
                            showCancel: false
                          })
                        }
                      })
                    }
                    // 用户选择“拒绝”,则弹层提示无法获取数据
                    if (res.cancel) {
                      wx.showModal({
                        title: '授权失败',
                        content: '无法使用定位权限,不能获取到数据',
                        confirmText: '知道了',
                        confirmColor: '#345391',
                        showCancel: false
                      })
                    }
                  }
                })
              }
            } else {
              // 还没有操作位置授权,暂时不做处理
            }
          }
        })
      }
    
    })

    所有代码都是可以直接复制使用,放到小程序里就可以执行了。但是需要自己申请小程序AppID和百度的ak值。

    附效果图:

     

  • 相关阅读:
    工厂模式--工厂方法模式(Factory Method Pattern)
    工厂模式--简单工厂模式( Simple Factory Pattern )
    blog2.0--Springboot添加redis缓存(注解方式)
    blog2.0--JSR303参数校验+全局异常处理器
    高并发秒杀——SpringBoot集成redis
    SpringBoot报错HHH000206: hibernate.properties not found
    blog2.0--保存博客文章到本地磁盘
    Swagger注解 传参
    设计模式--单例模式
    跳表
  • 原文地址:https://www.cnblogs.com/leafinwind/p/10298957.html
Copyright © 2011-2022 走看看