小程序

351 阅读8分钟

WXML

数据绑定

数据绑定,可以在文本中绑定数据,也可以在属性中绑定数据

<!-- index.wxml -->
    <view id="title">{{message}}</view>
    <view hidden="{{flag}}">Hidden</view>

<!-- index.js -->
Page({
    data: {
        message: "hello world",
        flag: true
    }
})

列表渲染

<!-- index.wxml 列表渲染 -->
  <view>
    <block wx:for="{{items}}" wx:for-item="item" wx:key="index">
      <view>{{item.name}}</view>
    </block>
  </view>

// index.js
Page({
    data: {
        "items": [
          { name: "商品A" },
          { name: "商品B" },
          { name: "商品C" }
        ]
    }
})

条件判断

<!-- index.wxml  条件判断 -->
  <view>
    <view wx:if="{{condition == 1}}">
      吃面食
    </view>
    <view wx:elif="{{condition == 2}}">
      吃米
    </view>
    <view wx:else>
      出去下馆子
    </view>
  </view>

// index.js
Page({
    data: {
        // 随机生成1~3的正整数
        condition: Math.floor(Math.random()*3+1)
    }
})

Hidden与if...else区别:

    相同:两者都选择性显示元素

    不同:Hidden无论条件是否成立,都会渲染,初始化开销较大;条件渲染if else根据条件创建和销毁,切换的开销较大

    Tips:如果需要频繁切换,则选用hidden

模板Template

  • 内部模板
<!-- 定义模板 -->
  <template name="tempItem">
    <view>
      <view>收件人:{{name}}</view>
      <view>联系方式:{{phone}}</view>
      <view>地址:{{address}}</view>
    </view>
  </template>
<!-- Template -->
  <view>
    <template is="tempItem" data="{{...tItem}}"></template>
    this is index.template
  </view>

// index.js
Page({
    data: {
        tItem: {
            name: "Jack",
            phone: "111",
            address: "广州"
        }
    }
})

  • 外部模板
    • import引入
      • <!-- index.wxml -->
          <import src="./a.wxml"></import>
          <!-- 使用import引入文件的模板 -->
          <template is="a"></template>
      • <!-- a.wxml -->
        <view>
          this is a.wxml title
          <template name="a">
            this is a.wxml template
          </template>
        </view>

    • include引入
      • <!-- b.wxml -->
        <view>
          this is b.title
          <view>
            <template name="b">
              this is b.template
            </template>
          </view>
        </view>
      • <!-- index.wxml -->
        <include src="./b.wxml"></include>
        <template is="b"></template>        

import与include两种引入方式区别:

  1. import引入的是目标文件的模板,只能引用目标文件中的模板,如果引入的目标文件中还引入并且使用其他文件嵌入的模板,嵌入的模板不会生效,避免死循环,比如说C引入了模板B,模板B引入了模板A,则模板C不会引入模板A的template
  2. include引入的是目标文件除了模板之外的全部内容

WXSS

外部样式的引入

index.wxss

/* 引入外部样式 */
@import "./temp.wxss";
.container{
  width: 100%;
  height: 44rpx;
  text-align: center;
  color: #333333;
}

temp.wxss

.container{  border: 1rpx solid #000000;}

选择器的权重(优先级)

  • import!          无穷大
  • style              1000
  • #element      100
  • .element       10
  • element        1

小程序JavaScript

组成:

  • ECMAScript
  • 小程序框架
  • 小程序API

不同平台的JS环境

  • IOS           JavaScriptCore
  • android    X5内核
  • IDE           nwjs

WXS

内部WXS

index.wxml

<!-- 内部WXS --> <wxs module="m1">  module.exports = {    message: "m1.wxs"  } </wxs> <view>{{m1.message}}</view>

外部WXS

index.wxml

<!-- 引入外部WXS --> 
<wxs src="./m2.wxs" module="m2"></wxs> 
<view>{{m2.message}}</view>

m2.wxs

module.exports = require('./m1.wxs')

m1.wxs

module.exports = {  message: "m2.wxs"}

注释

  • 单行注释     //
  • 多行注释     /*    */
  • 结尾注释     /*

数据类型

  • number     数值
  • string        字符串
  • boolean    布尔
  • object       对象
  • array         数组
  • function    函数
  • date          日期
  • regexp      正则

基础类库

  • console 
    • 只提供了console.log
  • Math
  • Json
  • Number
  • Date
  • Globel

底层架构:MINA框架

运行机制

启动:

  • 冷启动
    • 用户首次打开小程序,或者微信将小程序销毁(小程序退至后台五分钟后未使用或者短时间(5s)连续收到系统的告警)后,进入小程序
  • 热启动
    • 当用户退出小程序后,在一定时间内(5min)客户端会维持小程序的状态,重新进入小程序,手机将小程序从后台调至前台使用

加载机制

生命周期

小程序应用生命周期

  • onLaunch
    • 进入小程序时,客户端为自动为小程序配置运行环境,客户端会从CDN下载代码包或者从本地将代码包注入到运行环境,初始化完成后,客户端会给逻辑层的app.js的APP实例派发onLaunch事件,app.js构造器中onLaunch就会被调用
  • onShow
    • 再次进入小程序,逻辑层的app.js构造器中onShow就会被调用
  • onHide
    • 进入小程序,点击home或者退出小程序时,这时小程序并没有退出,而是挂至后台
  • onError
    • 小程序发生脚本错误,或者API调用失败后,就会触发onError方法,给onError方法传入错误信息

globalData:小程序应用全局数据

小程序页面生命周期

  • onLoad
    • 当页面首次加载时,逻辑层给配置实例派发onLoad事件,从页面加载到销毁,onLoad只会触发一次,从onLoad回调函数中可以获取页面打开的参数
  • onShow
    • 页面首次加载后onLoad触发,当前页面的onShow方法就会被调用,还有就是当从别的页面返回当上一级页面时,上一级页面的onShow方法也会被调用
  • onReady
    • 当onShow触发后,就会调用onReady就会被触发,和onLoad一样,从页面加载到销毁,onReady只会触发一次。onReady被调用后,逻辑层和视图层就可以开始交互
  • onHide
    • 当从一个页面跳至另一个页面的时候,就会触发onHide方法
  • onUnload
    • 当关闭页面的时候,就会触发onUnLoad方法

通常在onLoad和onShow请求服务端数据

data当前页面的数据

页面路由

路由方式

  • 初始化
    • 页面栈表现:新页面入栈
    • 触发时机:小程序打开的第一页面
    • 路由后页面:onLoad、onShow
  • 打开新页面
    • 页面栈表现:新页面入栈
    • 触发时机:调用API  wx.navigateTo  或者使用组件  <navigator open-tye="navigateTo"/>
    • 路由当前页:onHide
    • 路由后页面:onLoad、onShow
  • 页面重定向
    • 页面栈表现:当前页面出栈,新页面出栈
    • 触发时机:调用API wx.redirectTo 或者使用组件 <navigator open-tye="redirectTo"/>
    • 路由当前页:onUnload 
    • 路由后页面:onLoad、onShow
  • 页面返回
    • 页面栈表现:页面不断出栈,直至目标返回页,新页面入栈
    • 触发时机:调用API wx.navigateBack 或者使用组件 <navigator open-tye="navigateBack"/>
    • 路由当前页:onUnload
    • 路由后页面:onLoad、onShow
  • Tab切换
    • 页面栈表现:页面全部出栈,只留下新的tab页面
    • 触发时机:调用API wx.switchTab或者使用组件 <navigator open-tye="switchTab"/>
  • 重启动
    • 页面栈表现:页面全部出栈,只留下新的页面
    • 触发时机:调用API wx.reLaunch或者使用组件 <navigator open-tye="reLaunch"/>
    • 路由当前页:onUnload
    • 路由后页面:onLoad、onShow

事件

事件阶段

  • 事件捕获阶段(从外面到里面)
  • 事件处理阶段(事件触发绑定的函数执行)
  • 事件冒泡阶段(从里面到外面)

可捕获事件

  • touchstart(手指按下屏幕)
  • touchmove(手指在屏幕移动)
  • touchcancel(手指在屏幕中被其他操作打断如来电提醒等)
  • touchend(手指离开屏幕)
  • tap(手指点击屏幕)
  • longpress(手指长按屏幕)
  • longtap(手指长按屏幕,最后还会触发tap事件)

可冒泡事件

  • touchstart(手指按下屏幕)
  • touchmove(手指在屏幕移动)
  • touchcancel(手指在屏幕中被其他操作打断如来电提醒等)
  • touchend(手指离开屏幕)
  • tap(手指点击屏幕)
  • longpress(手指长按屏幕)
  • longtap(手指长按屏幕,会顺带触发tap事件)
  • transitionend(界面动画结束后)
  • animationstart(动画开始)
  • animationiteration(动画迭代一次后)
  • animationend(动画结束)
  • touchforcechange(3Dtouch结束后)

bind会绑定事件冒泡阶段,capture会绑定事件捕获阶段,catch会阻止事件冒泡阶段或者事件捕获阶段的调用

<!--index.wxml--><view class="container">  <view class="container-A" bindtap="clickA">    container-A    <view class="container-B" bindtap="clickB">      container-B      <view class="container-C" bindtap="clickC">        container-C      </view>    </view>  </view></view>

//index.js
Page({
  clickA() {    console.log("clickA")  },  clickB() {    console.log("clickB")  },  clickC() {    console.log("clickC")  }})

点击container-C:  clickC -> clickB -> clickA

<!--index.wxml--><view class="container">  <view class="container-A" capture-bind:tap="clickA">    container-A    <view class="container-B" capture-bind:tap="clickB">      container-B      <view class="container-C" capture-catch:tap="clickC">        container-C      </view>    </view>  </view></view>

//index.js
Page({
  clickA() {
    console.log("clickA")  
},
  clickB() {
    console.log("clickB")
  },
  clickC() {
    console.log("clickC")
  }})

点击container-B: clickA -> clickB 

组件

官方文档:developers.weixin.qq.com/miniprogram…

视图容器

基础内容

  • icon

  • process

  • text


  • richtext



    • <rich-text nodes="{{nodes}}" bindtap="tap"></rich-text>
    • Page({
        data: {
          nodes: [{
            name: 'div',
            attrs: {
              class: 'div_class',
              style: 'line-height: 60px; color: red;'
            },
            children: [{
              type: 'text',
              text: 'Hello&nbsp;World!'
            }]
          }]
        },
        tap() {
          console.log('tap')
        }
      })

表单组件

  • button






  • checkbox

  • editor
  • form
    • 表单。将组件内的用户输入的switch input checkbox slider radio picker 提交。当点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的value 值进行提交,需要在表单组件中加上 name 来作为 key


  • input

  • label
    • 用来改进表单组件的可用性。使用for属性找到对应的id,或者将控件放在该标签下,当点击时,就会触发对应的控件。 for优先级高于内部控件,内部有多个控件的时候默认触发第一个控件。 目前可以绑定的控件有:button, checkbox, radio, switch

  • picker






  • picker-view


  • radio

  • slider


  • switch

  • textarea

导航

  • functional-page-navigator



  • navigator

媒体组件

  • audio

  • camera

  • image


  • live-player






  • live-pusher





  • video