阅读 101

JB的小程序之旅-小程序基础(登录授权、请求数据)

前言

半年前说想学学小程序,当时写了个hello world,算是站在门外了解下,当时也写了篇文章,最终的收获是这么一张图:

image.png-311.9kB

这不,刚好小猪最近也在搞小程序,jb也就照着小猪的笔记顺便弄一波,主要目的是为了熟悉下小程序,初级用法,大神请绕路;

这里先默许,已经了解小程序的代码结构跟基本配置;

工具信息

需要先安装微信开发者工具、vscode、minapp(直接在vscode里安装);

配置过程

打开微信开发者工具,创建小程序项目,appid直接点击测试号小程序即可;

微信图片_20190517110815.png-15kB

创建完项目后,长这样的:

QQ截图20190517111257.jpg-83.4kB

因为用的是快速模板,所以里面会有默认代码,为了加深理解,手动把index.jsindex.wxmlindex.wxss都删除掉;

QQ截图20190517111620.jpg-7.8kB

首先把小程序的窗口配置一下,是在app.json,修改下标题背景颜色、文字颜色跟文本内容;

"navigationBarBackgroundColor": "#FFB6C1",
"navigationBarTitleText": "jb",
"navigationBarTextStyle":"white"
复制代码

预览图:

QQ截图20190517111953.jpg-3.9kB

设置头像

首先先新建assets目录存放静态资源,然后在index.wxml添加一个image控件;

<image src="../../assets/jb.jpg" />
复制代码

预览图:

QQ截图20190517112523.jpg-12.4kB

正常显示,但是如果要做头像,就太大了,调整下样式,打开index.wxss,添加个选择器:

.user-icon-image{
    width: 200rpx;
    height: 200rpx;
}
复制代码

然后在刚刚的image标签设置下属性:

<image class="user-icon-image" src="../../assets/jb.jpg" />
复制代码

预览图:

QQ截图20190517112838.jpg-5.4kB

如果想实现宽度100%,高度自适应,有两种方法:

# 方法1,直接使用百分比
.user-icon-image{
    width: 100%;
    height: 200rpx;
}

# 方法2,属性里面新增mode="widthFix"
<image class="user-icon-image" src="../../assets/jb.jpg" mode="widthFix"/>
复制代码

两种方法的效果都一样:

QQ截图20190517113524.jpg-7.8kB

登录授权获取头像

按照一般的习惯,登录都是要点击的,因此需要一个按钮,在index.wxml增加:

<button open-type="getUserInfo">获取头像昵称</button>
复制代码

预览图:

QQ截图20190517162831.jpg-17.8kB

点击授权即可完成授权,但是授权信息是不会保存起来的,因此需要写个函数保存下,而button下有一个属性:bindgetuserinfo,用户点击按钮的时候,会返回获取到用户的信息,因此在这里绑定一个用于保存用户信息回调方法即可,在index.js中添加代码:

//index.js
//获取应用实例
const app = getApp()

Page({
  getUserInfo: function(e) {
    app.globalData.userInfo = e.detail.userInfo
    console.log(app.globalData.userInfo)
  },
})
复制代码

然后index.wxml中的button绑定下属性:

<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">获取头像昵称</button>
复制代码

清一波缓存,点击按钮,查看Console输出,发现有打印结果,说明获取成功;

QQ截图20190517163932.jpg-62.9kB

一般来说,用户信息获取到,就需要替换头像了,因此需要添加两个变量,在index.js里面添加以下信息:

Page({
  data: {
    userInfo: {}, //用户信息
    hasUserInfo: false,//是否有用户信息
  },
复制代码

接着onLoad函数中完成初始化:

onLoad: function () {
if (app.globalData.userInfo) {
  this.setData({
    userInfo: app.globalData.userInfo,
    hasUserInfo: true
  })
}
},
# 这里的意思是,如果userInfo有数据,则set数据;
复制代码

接着index.wxml判断下数据是否可用,不可用的话显示默认图标和按钮,可用的话显示用户头像与昵称,这里需要说明下,获取到的信息都保存在userInfo里,根据上面的截图,头像的字段是avatarUrl,用户名的字段是nickName

<!--index.wxml-->
<block wx:if="{{!hasUserInfo}}">
    <image class="user-icon-image" src="../../assets/jb.jpg" />
    <button open-type="getUserInfo" bindgetuserinfo="getUserInfo">获取头像昵称</button>
</block>
<block wx:else>
    <image class="user-icon-image" src="{{userInfo.avatarUrl}}" />
    <text>{{userInfo.nickName}}</text>
</block>
复制代码

预览图:

QQ截图20190517165740.jpg-5kB

丰富异常情况的处理,直接贴官网的例子:

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    userInfo: {}, //用户信息
    hasUserInfo: false,//是否有用户信息
  },
  onLoad: function () {
    if (app.globalData.city){
        this.setData({
          city: app.globalData.city
        })
      console.log(app.globalData.city)
    }
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }
  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    console.log(app.globalData.userInfo)
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  },
})

复制代码

紧跟着调整样式:

.user-icon-wrapper{
      display:flex;                 
      justify-content: center; 
      flex-direction: column;
      align-items: center
} 
复制代码

然后index.wxml做下适配,增加view

<!--index.wxml-->
<block wx:if="{{!hasUserInfo}}">
    <view class="user-icon-wrapper">
        <image class="user-icon-image" src="../../assets/jb.jpg" />
        <button class="authorize-button" open-type="getUserInfo" bindgetuserinfo="getUserInfo">获取头像昵称</button>
    </view>
</block>
<block wx:else>
    <view class="user-icon-wrapper">
        <image class="user-icon-image" src="{{userInfo.avatarUrl}}" />
        <text>{{userInfo.nickName}}</text>
    </view>

</block>

复制代码

预览图:

QQ截图20190517170524.jpg-6.5kB

请求网络接口

天气接口用的是魅族天气api,接口地址:

http://aider.meizu.com/app/weather/listWeather?cityIds=101280601
复制代码

内容众多,直接显城市即可,index.wxml添加控件:

<button style="margin-top: 50rpx">刷新天气</button>
<view style="height: 100rpx;flex-direction:column;">
  <text>城市:{{city}}</text>
</view>
复制代码

请求接口,用的是wx.request,·index.js中新增:

  refreshWeather: function () {
        var myThis = this;
        wx.request({
          url: 'http://aider.meizu.com/app/weather/listWeather',
          data: {
            'cityIds': '101280601'
          },
          method: 'GET',
          headers: {
            'User-Agent:': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
            'Host':'aider.meizu.com'
          },
          success: function (res) {
            console.log(res.data);
            myThis.setData({
              city: res.data.value[0].city
            })
          },
          fail: function () {
            console.log("请求失败!");
          },
          complete: function () {
            console.log("请求完成!");
          }
        })
      },

复制代码

接着按钮设置下点击时触发这个网络请求:

<button style="margin-top: 50rpx" bindtap="refreshWeather">刷新天气</button>
复制代码

小程序开发者工具,右上角详情,勾选:

QQ截图20190517175118.jpg-37.5kB

点击下按钮,这样就能获取到数据啦~

QQ截图20190517175223.jpg-58.4kB

启动小程序时自动请求

这里有个想法,如果想启动小程序就直接请求接口显示数据,怎么搞?

点击按钮是set数据,但是启动后不允许set数据,因此只能先获取到数据,赋值,然后再获取;

首先,打开app.js,找到globalData,新增city全局变量:

  globalData: {
    userInfo: null,
    city:null
  }
复制代码

继续在app.js新增请求逻辑:

    // 设置city变量
    wx.request(
      {
      url: 'http://aider.meizu.com/app/weather/listWeather',
      data: {
        'cityIds': '101280601'
      },
      method: 'GET',
      headers: {
        'User-Agent:': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
        'Host':'aider.meizu.com'
      },
      success: function (res) {
        console.log(res.data);
        const appInstance = getApp()
        appInstance.globalData.city = res.data.value[0].city
        console.log(appInstance.globalData.city) // I am global data
      },
      fail: function () {
        console.log("请求失败!");
      },
      complete: function () {
        console.log("请求完成!");
      }
    })
复制代码

这里注意,跟之前不一样的是,成功后不是set数据,而是赋值,而全局变量是这样赋值的:

const appInstance = getApp()
appInstance.globalData.city = res.data.value[0].city
复制代码

这样,启动后就会自动显示城市;

QQ截图20190517180027.jpg-7kB

关注下面的标签,发现更多相似文章
评论