微信小程序

创建小程序

新建项目选择小程序项目,选择代码存放的硬盘路径,填入刚刚申请到的小程序的 AppID,给你的项目起一个好听的名字,最后,勾选 "创建 QuickStart 项目" (注意: 你要选择一个空的目录才会有这个选项),点击确定,你就得到了你的第一个小程序了,点击顶部菜单编译就可以在 IDE 预览你的第一个小程序。

框架

小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。一个小程序主体部分由app.js,app.json,app.wxss组成,必须放在项目的根目录
其中:
app.js 表示小程序逻辑
app.json 表示小程序公共设置
app.wxss 表示小程序公共样式表(可选)

一个小程序页面由四个文件组成,分别是:
js :页面逻辑
wxml: 页面结构
wxss: 页面样式(可选)
json: 页面配置(可选)

配置

app.json文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。
以下是一个包含了所有配置选项的 app.json :

{
  "pages": [
    "pages/index/index",
    "pages/logs/index"
  ],
  "window": {
    "navigationBarTitleText": "Demo"
  },
  "tabBar": {
    "list": [{
      "pagePath": "pages/index/index",
      "text": "首页"
    }, {
      "pagePath": "pages/logs/logs",
      "text": "日志"
    }]
  },
  "networkTimeout": {
    "request": 10000,
    "downloadFile": 10000
  },
  "debug": true
}

pages接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面。小程序中新增/减少页面,都需要对 pages 数组进行修改。

window用于设置小程序的状态栏、导航条、标题、窗口背景色。
注:HexColor(十六进制颜色值),如"#ff00ff"

tabBar如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面

其中 list 接受一个数组,数组中的每个项都是一个对象,其属性值如下:


逻辑层(App Service)

小程序开发框架的逻辑层由 JavaScript 编写。
逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
在 JavaScript 的基础上,我们做了一些修改,以方便地开发小程序。

App

App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。

getApp()
全局的 getApp() 函数可以用来获取到小程序实例。

var appInstance = getApp()
console.log(appInstance.globalData) // I am global data

Page

Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。



object 内容在页面加载时会进行一次深拷贝,需考虑数据大小对页面加载的开销

数据绑定

可以在page里通过WXML对数据进行绑定

<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

页面相关事件处理函数

onPullDownRefresh: 下拉刷新
onReachBottom: 上拉触底
onPageScroll: 页面滚动,参数为scrollTop,可自定义页面在垂直方向已滚动的距离(单位px)

自定义转发字段

Page({
  onShareAppMessage: function () {
    return {
      title: '自定义转发标题',
      path: '/page/user?id=123'
    }
  }
})

WXML

WXML(WeiXin Markup Language)是框架设计的一套标签语言,可以构建出页面的结构(类似DOM结构)。用以下一些简单的例子来看看 WXML 具有什么能力:

数据绑定

<view> {{message}} </view>

列表渲染

等价于v-for

<view wx:for="{{array}}"> {{item}} </view>

条件渲染

通过判断view的值来进行选择渲染

<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
Page({
  data: {
    view: 'MINA'
  }
})

模板

先声明一个模板,通过模板标签调用
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入

<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
Page({
  data: {
    staffA: {firstName: 'Hulk', lastName: 'Hu'},
    staffB: {firstName: 'Shang', lastName: 'You'},
    staffC: {firstName: 'Gideon', lastName: 'Lin'}
  }
})

事件

等价于v-on

<view bindtap="add"> {{count}} </view>
Page({
  data: {
    count: 1
  },
  add: function(e) {
    this.setData({
      count: this.data.count + 1
    })
  }
})

数据绑定

数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:

组件属性

<view id="item-{{id}}"> </view>

控制属性

<view wx:if="{{condition}}"> </view>

关键字

<checkbox checked="{{false}}"> </checkbox>

运算

可以在 {{}} 内进行简单的运算,支持的有如下几种方式:

三元运算

<view hidden="{{flag ? true : false}}"> Hidden </view>

算数运算

<view> {{a + b}} + {{c}} + d </view>

逻辑判断

<view wx:if="{{length > 5}}"> </view>

组合

也可以在 Mustache 内直接进行组合,构成新的对象或者数组。

<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>

列表渲染

wx:for

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

<view wx:for="{{array}}">
  {{index}}: {{item.message}}
</view>

使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>

block wx:for

类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:

<block wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>

事件

什么是事件

事件是视图层到逻辑层的通讯方式。
事件可以将用户的行为反馈到逻辑层进行处理。
事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
事件对象可以携带额外信息,如 id, dataset, touches。

事件的使用方式

在组件中绑定一个事件处理函数。
如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>

详细的事件如下


引用

WXML 提供两种文件引用方式import和include。

import

import可以在该文件中使用目标文件定义的template,如:
在 item.wxml 中定义了一个叫item的template:

<template name="item">
  <text>{{text}}</text>
</template>

在 index.wxml 中引用了 item.wxml,就可以使用item模板:

<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>

import 的作用域

import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。

include

include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置

<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>

<view> header </view>
<view> footer </view>

wxss

WXSS 用来决定 WXML 的组件应该怎么显示。
与 CSS 相比,WXSS 扩展的特性有:
尺寸单位
样式导入

尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

样式导入

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。

.small-p {
  padding:5px;
}
@import "common.wxss";
.middle-p {
  padding:15px;
}

组件

框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。

什么是组件

组件是视图层的基本组成单元。
组件自带一些功能与微信风格的样式。
一个组件通常包括开始标签和结束标签,属性用来修饰这个组件,内容在两个标签之内。

<tagname property="value">
  Content goes here ...
</tagname>

view

视图容器相当于div,我们往里面写内容或嵌套标签


scroll-view

一块可以滚动的区域,可以通过修改属性实现滚动效果

swiper

轮播图

movable-view

可移动的视图容器,在页面中可以拖拽滑动

cover-view

覆盖在原生组件之上的文本视图,可覆盖的原生组件包括map、video、canvas、camera、live-player、live-pusher

camera

调用系统相机,需先调用wx.createCameraContext

wx.createCameraContext(this)

创建并返回 camera 上下文 cameraContext 对象,cameraContext 与页面的 camera 组件绑定,一个页面只能有一个camera,通过它可以操作对应的 <camera/> 组件。

// camera.js
Page({
    takePhoto() {
        const ctx = wx.createCameraContext()
        ctx.takePhoto({
            quality: 'high',
            success: (res) => {
                this.setData({
                    src: res.tempImagePath
                })
            }
        })
    },
    error(e) {
        console.log(e.detail)
    }
})

API

wx.navigateTo保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面
wx.setNavigationBarTitle动态设置当前页面的标题。
wx.showLoading(OBJECT)显示 loading 提示框, 需主动调用 wx.hideLoading才能关闭提示框

自定义组件

类似于页面,一个自定义组件由 json wxml wxss js 4个文件组成。要编写一个自定义组件,首先需要在 json 文件中进行自定义组件声明

{
  "component": true
}

组件的配置需要在.js文件里书写,通过component注册组件,并提供组件的属性定义、内部数据和自定义方法。

Component({
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    innerText: {
      type: String,
      value: 'default value',
    }
  },
  data: {
    // 这里是一些组件内部数据
    someData: {}
  },
  methods: {
    // 这里是一个自定义方法
    customMethod: function(){}
  }
})

使用自定义组件

使用自定义组件,需要在调用组件的页面的.json文件里进行引用声明

{
  "usingComponents": {
    "component-tag-name": "path/to/the/custom/component"
  }
}

组件模版

组件模版的写法与页面模板相同

组件模板中可以提供一个slot标签,可以获取到插入模板中的内容

<!-- 组件模板 -->
<view class="wrapper">
  <view>这里是组件的内部节点</view>
  <slot></slot>
</view>
<!-- 引用组件的页面模版 -->
<view>
  <component-tag-name>
    <!-- 这部分内容将被放置在组件 <slot> 的位置上 -->
    <view>这里是插入到组件slot中的内容</view>
  </component-tag-name>
</view>

组件样式

组件对应 wxss 文件的样式,只对组件wxml内生效
指定组件默认样式可以使用:host选择器

:host {
  color: yellow;
}

Component构造器

Component构造器可用于定义组件,调用Component构造器时可以指定组件的属性、数据、方法等。

定义段 类型 是否必填 描述
properties Object Map 组件的对外属性,是属性名到属性设置的映射表,属性设置中可包含三个字段, type 表示属性类型、 value 表示属性初始值、 observer 表示属性值被更改时的响应函数
data Object 组件的内部数据,和 properties 一同用于组件的模版渲染
methods Object 组件的方法,包括事件响应函数和任意的自定义方法
ready Function 组件生命周期函数,在组件布局完成后执行,此时可以获取节点信息

checkbox

多项选择器,内部由多个checkbox组成。
bindchange<checkbox-group/>中选中项发生改变时触发 bindchange事件

可绑定的属性如下

属性名 类型 说明
value string 发生change事件时,表示选中checkbox的标识
disabled Boolean 禁用
checked Boolean 是否选中状态
color color checkbox的颜色
<checkbox-group bindchange="checkboxChange">
  <label class="checkbox" wx:for="{{items}}">
    <checkbox value="{{item.name}}" checked="{{item.checked}}"/>{{item.value}}
  </label>
</checkbox-group>

input

输入框,用法与HTML相同,具体属性参考微信小程序文档

label

用来关联其他表单元素,用法与HTML相同,提供for属性来查找id进行关联

picker

从底部弹起的滚动选择器,现支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。

普通选择器

<view class="section__title">普通选择器</view>
  <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
    <view class="picker">
      当前选择:{{array[index]}}
    </view>
  </picker>

普通选择器提供以下属性进行修饰

属性名 类型 说明
range String 表示进行选择的对象数组时,通过range-key来指定对象中的key值作为选择器显示内容
value Number 表示该值是range中的第几个(下标值)
bindchange event value改变时触发的事件
bindcancel event 当取消选择或点遮罩层收起 picker 时触发

时间选择器

通过设定最小时间和最大时间,在该范围内进来时间选择

<view class="section__title">时间选择器</view>
  <picker mode="time" value="{{time}}" start="09:01" end="21:01" bindchange="bindTimeChange">
    <view class="picker">
      当前选择: {{time}}
    </view>
  </picker>

时间选择器提供以下新属性

属性名 类型 说明
value string 表示选中的时间
start string 表示有效时间范围的开始
end string 表示有效时间范围的结束,字符串格式为"hh:mm"

选择器的联动

当我们需要实现通过选择省份后,市和区同时发生改变,可以通过bindcolumnchange方法来进行监听

<picker mode="multiSelector" bindcolumnchange="onColChange" bindchange="onpickerCha" range="{{arr2}}"value="{{index}}">
我的儿子是:{{arr2[0][index[0]]}}------{{arr2[1][index[1]]}}
</picker>
onColChange(e){
    if(e.detail.value==1){
      this.setData({
        'arr2[1]':["aa","bb"]
      })
    }
    if(e.detail.value==0){
      this.setData({
        'arr2[1]':["男","女"]
      })
    }
  },

radio

radio-group
单项选择器,内部由多个<radio/>组成。
radio的属性同上checkbox

<radio-group class="radio-group" bindchange="radioChange">
  <label class="radio" wx:for="{{items}}">
    <radio value="{{item.name}}" checked="{{item.checked}}"/>{{item.value}}
  </label>
</radio-group>

登录小程序

小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。开发者服务器以code换取 用户唯一标识openid 和 会话密钥session_key。

wx.login

调用接口wx.login() 获取临时登录凭证(code)
可选参数如下

属性名 类型 说明
timeout Number 超时时间,单位 ms
success Function 接口调用成功的回调函数
fail Function 接口调用失败的回调函数
complete Function 接口调用结束的回调函数(调用成功、失败都会执行)

其中success接收两个参数
errMsg表示成功调用的结果
code是成功调用后返回的用户登录凭证(有效期五分钟),开发者需要在开发者服务器后台调用 api,使用 code 换取 openid 和 session_key 等信息

App({
  onLaunch: function() {
    wx.login({
      success: function(res) {
        if (res.code) {
          //发起网络请求
          wx.request({
            url: 'https://test.com/onLogin',
            data: {
              code: res.code
            }
          })
        } else {
          console.log('登录失败!' + res.errMsg)
        }
      }
    });
  }
})

wx.getUserInfo

通过该接口可以拿到用户的个人信息,但是如果没有得到用户授权便调用该接口则直接报错
成功调用后的回调函数参数如下

参数 类型 说明
userInfo OBJECT 用户信息对象,不包含 openid 等敏感信息
encryptedData String 包括敏感数据在内的完整用户信息的加密数据
iv String 加密算法的初始向量(如果需要获取用户的隐私信息则需要同时调用encryptedData和iv)

获取到useInfo后你可以通过以下参数获取用户信息

属性名 类型 说明
nickName String 用户昵称
city String 用户所在城市
province String 用户所在省份
country String 用户所在国家
language String 用户的语言,(简体中文为zh_CN)
Page({
  data: {
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  onLoad: function() {
    // 查看是否授权
    wx.getSetting({
      success: function(res){
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称
          wx.getUserInfo({
            success: function(res) {
              console(res.userInfo)
            }
          })
        }
      }
    })
  },
  bindGetUserInfo: function(e) {
    console.log(e.detail.userInfo)
  }
})

wx.showModal

​显示模态弹窗,相当于提示框

wx.showModal({
  title: '提示',
  content: '这是一个模态弹窗',
  success: function(res) {
    if (res.confirm) {
      console.log('用户点击确定')
    } else if (res.cancel) {
      console.log('用户点击取消')
    }
  }
})

wx.requestPayment

发起微信支付
该接口有五个必填的属性
timeStamp:时间戳,即当前的时间
nonceStr:随机字符串,长度为32个字符以下,用来作标识
package:统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
signType:签名算法,暂支持 MD5
paySign:签名
通常情况下这五个数据都会由后台提供给我们

wx.createAnimation

创建一个动画实例animation调用实例的方法来描述动画。最后通过动画实例的export方法导出动画数据传递给组件的animation属性。

<view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx"></view>

wx.createAnimation可传四个参数分别是

属性名 类型 说明
duration 整数 动画的持续时间
timingFunction string 定义动画的效果
delay 整数 动画的延迟播放时间
transformOrigin string 设置元素旋转的基点

animation

通过调用wx.createAnimation生成的动画对象animation我们可以描述动画
可用属性请参考文档

step

当我希望在动画的第一步执行完后再执行第二步时,可以在执行完的动画后面加上step()来标识一组动画的完成。step 可以传入一个跟 wx.createAnimation() 一样的配置参数用于指定当前组动画的配置。

Page({
onShow: function(){
    var animation = wx.createAnimation({
      duration: 1000,
        timingFunction: 'ease',
    })
    this.animation = animation
    animation.scale(2,2).rotate(45).step()
    this.setData({
      animationData:animation.export()
    })
  }
})

wx.scanCode

当我们需要使用手机上的二维码时,可以通过调用该方法调起客户端扫码界面

// 允许从相机和相册扫码
wx.scanCode({
  success: (res) => {
    console.log(res)
  }
})

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

推荐阅读更多精彩内容