微信小程序开发(一)

微信小程序开发

                                                                作者:下家山

一:注册

如何找到注册的网址,百度吧

 一个邮箱只能注册一个微信小程序,但对手机,微信没有限制,所以我重新注册了一个qq,以获得新邮箱

 

 

二:工具下载

三:进入开发

3.1 新建项目

3.2 文件结构

运行效果

主页面---index           鼠标点击头像进入子页-----logs

 

3.2.1 index.js负责页面逻辑

3.2.2 index.json负责页面配置

3.2.3 index.wxml负责页面结构

3.2.4 index.wxss负责页面样式

 

3.3 app解析

App.json全局配置

微信官方文档

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html

 

{

  "pages": [

    "pages/index/index",

    "pages/logs/logs"

  ],

  "window": {

    "backgroundTextStyle": "light",

    "navigationBarBackgroundColor": "#fff",

    "navigationBarTitleText": "WeChat",

    "navigationBarTextStyle": "black"

  },

  "style": "v2",

  "sitemapLocation": "sitemap.json"

}

负责页面配置,json语法格式(都是字典形式,或者字典套字典),最外层的花括号{}表示一个无名字典,然后里面是四个键值对,分别是

   Key(键):value(值)   

“pages”:+列表,        

”window”:+字典(也就是字典里面套字典了)

“style”:+字符串

“sitemapLocation”:+字符串

关键字”pages”

关键字“pages”表示整个小程序的配置页面,如果去掉"pages/index/index",则看不到第一页,程序装载后直接显示的是第二页,如图

关键字”window”

关键字”window”是对整体窗体的控制,以及外观配置

"backgroundTextStyle":"light",//用于控制view中的上拉下拉加载效果,只能是light/dark两种选择,一种亮色,一种暗色,如果设置其他,比如设置为black,编译出错,提示:

ppJSON["window"]["backgroundTextStyle"] 字段需为 dark light

    "navigationBarBackgroundColor": "#fff",

    "navigationBarTitleText": "WeChat",

    "navigationBarTextStyle": "black"

  这三行,是设置导航栏的,我们可以改动一下,看看导航栏在哪个位置

关键字”style”

"style": "v2",是为了说明组件库版本采用的是新版v2

在下面的连接中可以找到所有基础版本库说明

https://developers.weixin.qq.com/miniprogram/dev/framework/release/v2.html

Style官方说明

基础库 2.8.0 开始支持,低版本需做兼容处理

微信客户端 7.0 开始,UI 界面进行了大改版。小程序也进行了基础组件的样式升级。app.json 中配置 "style": "v2"可表明启用新版的组件样式。

本次改动涉及的组件有 button icon radio checkbox switch slider。可前往小程序示例进行体验。

关键字“sitemapLocation

"sitemapLocation": "sitemap.json"

文件sitemap.json内容

{

  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",

  "rules": [{

  "action": "allow",

  "page": "*"

  }]

}

关键字sitemapLocation的作用主要是设置是否允许微信能否搜索小程序内的页面

官方说明:

微信现已开放小程序内搜索,开发者可以通过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler场景值1129。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。

# sitemap 配置

小程序根目录下的 sitemap.json 文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有 sitemap.json ,则默认为所有页面都允许被索引;

app.wxss全局样式

app.wxss作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。

/**app.wxss**/

.container {

  height: 100%;

  display: flex;

  flex-direction: column;

  align-items:center;

  justify-content: space-between;

  padding: 200rpx 0;

  box-sizing: border-box;

}

我们改动align-items做实验,看变化结果

Align-items表示所有条目垂直对齐方式,我们这里是居中对齐,它有以下对齐方式

,如果我们改为baseline,效果如下

  Baseline(左侧)对齐                              center(居中)对齐

  

App.wxss会作用于局部样式文件index.wxss和logs.wxss,我们从index.wxss和logs.wxss中可以看到使用了container类。

App.js全局逻辑

官方说明

https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html

 

App()函数

App(Object object)

注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果

 

//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

      }

    })

    // 获取用户信息

    wx.getSetting({

      success: res => {

        if (res.authSetting['scope.userInfo']) {

          // 已经授权,可以直接调用 getUserInfo 获取头像暱称,不会弹框

          wx.getUserInfo({

            success: res => {

              // 可以将 res 发送给后台解码出 unionId

              this.globalData.userInfo = res.userInfo

 

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回

              // 所以此处加入 callback 以防止这种情况

              if (this.userInfoReadyCallback) {

                this.userInfoReadyCallback(res)

              }

            }

          })

        }

      }

    })

  },

  globalData: {

    userInfo: null

  }

})

 

onLaunch(Object object)

小程序初始化完成时触发,全局只触发一次。参数也可以使用 wx.getLaunchOptionsSync 获取。

 

Logs

// 展示本地存储能力

    var logs = wx.getStorageSync('logs') || []

    logs.unshift(Date.now())

    wx.setStorageSync('logs', logs)

这一段代码的理解,就如注释所说,是展示本地存储能力,

var logs = wx.getStorageSync('logs') || []这一句是通过名字logs获取数组里面的内容,如果是第一次(首次数组为空,获取到为假),则把空数组[]复制给logs;

logs.unshift(Date.now())是获取当前时间,并且插入数组logs中,unshift是前插,也叫头部插入。

大家可以直接logs.unshift(1),看看效果

如果是1,则插入格林威治初始时间

 

Logs.push(1)则是尾部插入,每次时间会累加历使数据

logs.shift()头部删除   logs.unshift()头部插入

logs.pop()尾部删除   logs.push()尾部插入

wx对象

Object wx

小程序 API 全局对象,用于承载小程序能力相关 API。具体请参考小程序 API 参考文档

# wx.env

小程序环境变量对象

 

wx.login()

    // 登录

    wx.login({

      success: res => {

        // 发送 res.code 到后台换取 openId, sessionKey, unionId

      }

    })

Res=>是一个函数,叫箭头函数

X=>x*x

相当于

Function(x)

{

   Return x*x;

}

所以res=>{}相当于function(res){}

    // 登录

    wx.login({

      success: res => {

        console.log("登陆信息:",res)

        // 发送 res.code 到后台换取 openId, sessionKey, unionId

      }

    })

我们通过console.log打印出登陆成功的返回值得到:

登陆信息: {errMsg: "login:ok", code: "02167XtM1w2bE9161KsM12wkuM167Xtm"}

Login:ok表示成功登陆,你可以试试不用手机扫码登陆,看看返回值

wx.getSetting获取用户信息

    // 获取用户信息

    wx.getSetting({

      success: res => {

        console.log("认证信息:", res)

        if (res.authSetting['scope.userInfo']) {

          // 已经授权,可以直接调用 getUserInfo 获取头像暱称,不会弹框

          wx.getUserInfo({

            success: res => {

              // 可以将 res 发送给后台解码出 unionId

              console.log("用户信息:", res)

              this.globalData.userInfo = res.userInfo

 

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回

              // 所以此处加入 callback 以防止这种情况

              if (this.userInfoReadyCallback) {

                this.userInfoReadyCallback(res)

              }

            }

          })

        }

      }

    })

  }

我添加了两条语句,为了获取认证信息和用户信息

console.log("认证信息:", res)

console.log("用户信息:", res)

运行结果:

globalData全局变量

  globalData: {

    userInfo: null

  }

globalData是字典,里面的userInfo初值为Null空,等待后续赋值。

3.4 index解析

//index.js

//获取应用实例

const app = getApp()

 

Page({

  data: {

    motto: 'Hello World',

    userInfo: {},

    hasUserInfo: false,

    canIUse: wx.canIUse('button.open-type.getUserInfo')

  },

  //事件处理函数

  bindViewTap: function() {

    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.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

    this.setData({

      userInfo: e.detail.userInfo,

      hasUserInfo: true

    })

  }

})

 

Index.wxml 页面结构

Button标签

这里面的逻辑关系,在index.wxml代码第4行

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

Wx:if是一个判断语句,hasUserInfo第一次装载页面时时falsecanIUse是一个字典中的key,它的值value是有定义的,所以这里&&后面应该时为真的,但前面hasUserInfo再非一次(!表示取反)则为真,因此,wx:if里面为真,因此会显示“获取头像暱称”字样在界面上。

如果我们点击按钮”获取头像暱称”,则会触发绑定的函数调用getUserInfo

该函数定义在Index.js中的第46行。

其中,hasUserInfo会赋值为真true.

这样再次刷新页面时,不会再显示“获取图像暱称”,而会显示真实图像了

,注意需要微信扫码登陆

Image标签

    <block wx:else>

      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>

      <text class="userinfo-nickname">{{userInfo.nickName}}</text>

    </block>

Wx:else是和button中的wx:if对应的,当if条件不成立时则会进入else,即显示image

Image通过Bindtap绑定到函数bindViewTapbindtap是一个点击事件,这样当点击了头像时,则执行bindViewTap函数,该函数定义在index.js中的13

  //事件处理函数

  bindViewTap: function() {

    wx.navigateTo({

      url: '../logs/logs'

    })

  },

在这个函数中,wx.navigateTo()是一个界面切换函数,url:’../logs/logs’则会告诉wx.navigateTo切换到上级目录下面的logs文件夹下面的logs.js从而装载下一个页面logs.js

Text标签

<text class="userinfo-nickname">{{userInfo.nickName}}</text>

这一段控制的是头像下面的暱称名称

字体和颜色的控制是通过index.wxss中的userinfo-nickname类来控制的

/**index.wxss**/

.userinfo {

  display: flex;

  flex-direction: column;

  align-items: center;

}

 

.userinfo-avatar {

  width: 128rpx;

  height: 128rpx;

  margin: 20rpx;

  border-radius: 50%;

}

 

.userinfo-nickname {

  color: #aaa;

}

 

.usermotto {

  margin-top: 200px;

}

Motto显示

Motto:是座右铭,格言,警句的意思

  <view class="usermotto">

    <text class="user-motto">{{motto}}</text>

  </view>

Class=”usermotto”表示使用index.wxss中的usermotto样式控制

.usermotto {

  margin-top: 200px;//表示别名显示离上面的图片image200个像素距离

}

{{motto}}中的motto是微信小程序中的对变量的引用语法格式,这个变量定义在index.js

Page({

  data: {

    motto: 'Hello World',//变量motto的定义和初始化,它其实也是一个键值对

    userInfo: {},

    hasUserInfo: false,

    canIUse: wx.canIUse('button.open-type.getUserInfo')

  },

  Index.wxml视图层view

  

Index.wxml负责页面结构,这种结构通常通过view来管理,这里有三个view(第一层view),一个大view,包含两个小view(第二层view控制)

而这些view层的样式控制是通过app.wxss和index.wxss文件来控制的,

App.wxss负责大view的样式,index.wxss负责小view的样式。这三个文件的关系如下:

3.5 logs解析

Logs整个的页面是为了展现本地存储能力的,所以是通过日志(打印当前时间,每次加载子页面的时间)

效果如图

Logs.js子页面逻辑

//logs.js

const util = require('../../utils/util.js')

//requre包含另一个文件,相当于includeimport

Page({

  data: {

    logs: []//空列表,方便后面追加

  },

  onLoad: function () {

    console.log("装载logs页面....")

    this.setData({

      //app.js中已经调用wx.setStorageSync('logs', logs)设置了当前时间

      logs: (wx.getStorageSync('logs') || []).map(log => {

        //通过util.js中的格式化操作把时间转成字符串

        return util.formatTime(new Date(log))

      })

    })

  }

})

Logs.json解析

{

  "navigationBarTitleText": "查看启动日志",

  "usingComponents": {}

}

页面配置文件,设置导航栏标题,切换到logs页面时的“查看启动日志”就是这里设置的

Logs.wxml解析

Logs页面结构设计,即打印日志的格式,样式

<!--logs.wxml-->

<view class="container log-list">

  <block wx:for="{{logs}}" wx:for-item="log">

    <text class="log-item">{{index + 1}}. {{log}}</text>

  </block>

</view>

 

这里有循环语句wx:for,会统计日志的行数,index从0开始计数,所以+1,方便用户看

Logs.wxss解析

.log-list {

  display: flex;

  flex-direction: column;

  padding: 40rpx;

}

.log-item {

  margin: 10rpx;

}

 

 

负责logs.wxml结构显示的样式

3.6 util.js解析

formatTime是一个函数,参数就是date

=>后面的花括号是函数体,其中的year,month,day,hour,minute,second每个变量占用一条语句,js中的语句不需要分号,换行就行了

const formatTime = date => {

  const year = date.getFullYear()  //取得参数date中的年

  const month = date.getMonth() + 1//取得参数date中的月,因为月从0开始,所以要+1

  const day = date.getDate()    //得到天

  const hour = date.getHours()  //得到小时

  const minute = date.getMinutes() //得到分钟

  const second = date.getSeconds()  //得到秒

  //返回年月日,时分秒,年月日以/隔开,时分秒以:隔开,形如2020/02/25 20:21:34

  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')

}

//把列表转成字符串

const formatNumber = n => {

  n = n.toString()

  return n[1] ? n : '0' + n   //这一句没有什么意义,去掉也没问题

}

 

module.exports = {

  formatTime: formatTime//导出函数,供外部调用(logs.js)

}

 新建工程,工程模板的解析就到这里,接下来我们学习如何自己开发一个简单小程序,包括两个页面,一个按钮。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章