微信小程序开发入门教程

作者也是刚开始接触小程序开发,不足之处请指正。

目录

先看工程目录,index、logs、mine、wallet这几个文件夹可以看做一个个页面,每个文件夹(页面)里有四个文件:.js .json .wxml .wxss

.js文件就是JavaScript,写逻辑相关的代码
.json文件做一些固定的配置
.wxml类似于html写控件
.wxss类似于css 写控件的样式

具体来看
创建一个小程序项目会默认有app.js,app.json,app.wxss这三个文件作用于是整个小程序,而每个页面里的这几个文件的作用域是当前页面。

先来看官方默认创建的代码

//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        console.log('code',res)
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        console.log('setting',res.authSetting)
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallbacks) {
                this.userInfoReadyCallbacks(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  }
})

onLaunch函数是小程序生命周期函数,监听小程序初始化。即小程序入口,通过查阅官方文档可以看到此函数的解释。


屏幕快照 2019-07-16 下午3.42.44.png

下面来分析 var logs = wx.getStorageSync('logs') || [],wx.调用的wx.getStorageSync一看就是微信官方API,这行代码是同步获取key为'logs'的缓存,且logs变量类型为数组。通过查阅官方API可以看到此函数的定义,同步获取缓存也就是会阻塞当前线程的意思喽,即获取完这个数组才会继续执行代码。


API

logs.unshift(Date.now())又是啥意思呢,查询微信官方API发现unshift方法是ES5标准里的,意思是在数组的最前面插入一个元素,这里是插入了当前时间戳。

wx.setStorageSync('logs', logs)从字面看就是同步保存这个被修改的数组到缓存中。

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        console.log('code',res)
      }
    })
屏幕快照 2019-07-16 下午3.47.09.png

这个wx.login是什么意思,wx.开头即微信提供的API,意思是调用了login接口获取登录凭证(code),调用成功即success会返回code,然后向我们自己的服务器请求换取openId, sessionKey, unionId这些信息,来进行登录操作。

    // 获取用户信息
    wx.getSetting({
      success: res => {
        console.log('setting',res.authSetting)
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallbacks) {
                this.userInfoReadyCallbacks(res)
              }
            }
          })
        }
      }
    })

wx.getSetting用来获取小程序已经向用户请求过的权限,返回形式是一个字典(key:value)形式,其中'scope.userInfo'就是获取用户信息的key,如果这项为true就是获取到用户信息的意思。


屏幕快照 2019-07-16 下午3.52.14.png

wx.getUserInfo用来获取用户信息,success就会返回用户信息

this.globalData.userInfo = res.userInfo,this类似于iOS开发中的self,globalData是自定义的一个全局变量,内部数据结构是有一个userInfo,用来全局保存用户信息。

this.userInfoReadyCallbacks又是个什么呢,类似于iOS开发中的block(闭包),函数名随便取,我就在后面加了个s, 用来异步反向传值,因为wx.getUserInfo这个接口是异步获取的,有可能会在index的js里的onLoad方法之后返回,如果index页面调用了userInfoReadyCallbacks来接收userInfo数据,则app.js里会执行this.userInfoReadyCallbacks(res),就可以异步给index页面传值了。

//index.js
      app.userInfoReadyCallbacks = res => {
        if (res.userInfo) {
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      }

下面来看index.js文件

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

Page({
  data: {
    motto: '尬先生尬先生尬先生尬先生尬先生尬先生尬先生尬先生',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')//固定写法 通过button获取用户信息只能这么写
  },
  //事件处理函数
  bindViewTap: function () {//点击头像跳转logs页面
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse) {
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallbacks = res => {
        if (res.userInfo) {
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          if (res.userInfo) {
            app.globalData.userInfo = res.userInfo
            this.setData({
              userInfo: res.userInfo,
              hasUserInfo: true
            })
          }
        }
      })
    }
  },

  getUserInfoClick: function (e) {//点击了拒绝或同意后会回调
    if (e.detail.userInfo) {
      app.globalData.userInfo = e.detail.userInfo
      this.setData({
        userInfo: e.detail.userInfo,
        hasUserInfo: true
      })
    }
  }
})

const app = getApp()获取应用实例,这样就可以使用全局变量了。

 data: {
    motto: '尬先生尬先生尬先生尬先生尬先生尬先生尬先生尬先生',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')//固定写法 通过button获取用户信息只能这么写
  },

定义了一个名为data的数据结构,有四个元素motoo是一个字符串,userInfo用户信息,hasUserInfo是否获取到了用户信息bool类型,canIUse判断小程序的API,回调,参数,组件等是否在当前版本可用,当前是判断button里获取用户信息在当前版本是否可用,'button.open-type.getUserInfo'就是通过button获取用户信息的固定写法。


屏幕快照 2019-07-16 下午4.50.48.png

bindViewTap: function () 是在index.wxml里绑定的头像image点击事件,即登录以后点击头像进行后续操作。

    wx.navigateTo({
      url: '../logs/logs'
    })

wx.navigateTo保留当前页面,跳转到应用内的某个页面,url: '../logs/logs'即跳转到logs页面

  if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    }

如果在app.js页面获取userInfo速度快于index.js的onLoad方法,走这里。 this.setData给data赋值的同时会主动刷新index.wxml里的UI数据。

  getUserInfoClick: function (e) {//点击了拒绝或同意后会回调
    if (e.detail.userInfo) {
      app.globalData.userInfo = e.detail.userInfo
      this.setData({
        userInfo: e.detail.userInfo,
        hasUserInfo: true
      })
    }
  }

getUserInfoClick是在index.wxml里绑定的bindgetuserinfo="getUserInfoClick"即button的点击以后弹出的权限授权框的点击事件回调。

下面看下index.wxml文件

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfoClick"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>

<view>标签视图容器,class="container",给这个view起个名字,方便在index.wxss文件里给这个标签设置样式。

    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfoClick"> 获取头像昵称 </button>

<button>标签,wx:if="{{!hasUserInfo && canIUse}}"如果同时满足!hasUserInfo && canIUse这两个条件则绘制这个button,open-type="getUserInfo"意思是这个button点击后用来请求用户信息是固定写法。bindgetuserinfo="getUserInfoClick"绑定一个名为getUserInfoClick的函数作为授权弹窗的回调方法。


屏幕快照 2019-07-16 下午5.07.10.png
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>

<block>如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,这里包装了一个<image>和一个<text>标签。

{{userInfo.nickName}}包裹变量用两个花括号包装起来。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容