1.安装微信开发者工具

window 64:
https://servicewechat.com/wxa...
window 32:
https://servicewechat.com/wxa...
mac:
https://servicewechat.com/wxa...

2.创建新项目

开发者工具安装完成后,打开并使用微信扫码登录。选择添加“项目”,填入AppID,如果没有,选择无AppleID,命名"myWeChat",并选择一个本地的文件夹作为代码存储的目录,点击“添加项目”,此时开发者工具会提示,是否需要创建一个 quick start 项目。选择“是”,开发者工具会帮助我们在开发目录里生成一个简单的 demo。

3.编写代码

点击开发者工具左侧导航的“编辑”,可以看到这个项目,已经初始化并包含了一些简单的代码文件。最关键也是必不可少的,是 app.js、app.json、app.wxss 这三个。其中,.js后缀的是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件。微信小程序会读取这些文件,并生成小程序实例。
app.js是小程序的脚本代码。我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量。调用框架提供的丰富的 API,如本例的同步存储及同步读取本地数据。

app.js:

App({
  onLaunch: function () {
    console.log('App Launch');
    //调用API从本地缓存中获取数据
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)
  },
  onShow: function () {
    console.log('App Show')
  },
  onHide: function () {
    console.log('App Hide')
  },
  getUserInfo:function(cb){
    var that = this
    if(this.globalData.userInfo){
      typeof cb == "function" && cb(this.globalData.userInfo)
    }else{
      //调用登录接口
      wx.login({
        success: function () {
          wx.getUserInfo({
            success: function (res) {
              that.globalData.userInfo = res.userInfo
              typeof cb == "function" && cb(that.globalData.userInfo)
            }
          })
        }
      })
    }
  },
  globalData:{
    userInfo:null,
    currData: 'I am is global data'
  }
})

app.json 是对整个小程序的全局配置。我们可以在这个文件中配置小程序是由哪些页面组成,配置小程序的窗口背景色,配置导航条样式,配置默认标题。注意该文件不可添加任何注释。

app.json:

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs",
    "pages/newPage/newPage"
  ],
  "window":{
    "backgroundColor": "#49CB5F",
    "backgroundTextStyle":"dark",
    "navigationBarBackgroundColor": "#F8DBF8",
    "navigationBarTitleText": "xhh",
    "navigationBarTextStyle": "black",
    "enablePullDownRefresh": true
  },
  "tabBar": {
    "color": "#B91ABB",
    "selectedColor": "#A349A4",
    "backgroundColor": "#F8DBF8",
    "borderStyle": "white",
    "list": [{
      "pagePath": "pages/index/index",
      "iconPath": "image/icon_component.png",
      "selectedIconPath": "image/icon_component_HL.png",
      "text": "首页"
    }, {
      "pagePath": "pages/logs/logs",
      "iconPath": "image/icon_API.png",
      "selectedIconPath": "image/icon_API_HL.png",
      "text": "日志"
    },{
      "pagePath": "pages/newPage/newPage",
      "iconPath": "image/wechat.png",
      "selectedIconPath": "image/wechatHL.png",
      "text": "其他"
    }]
  },
  "networkTimeout": {
    "request": 10000,
    "downloadFile": 10000,
    "uploadFile": 10000,
    "connectSocket": 10000
  },
  "debug": false
}

app.wxss 是整个小程序的公共样式表。我们可以在页面组件的 class 属性上直接使用app.wxss 中声明的样式规则。

app.wxss:

.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  /*padding: 200rpx 0;*/
  padding-top: 200rpx;
  box-sizing: border-box;
} 

4.创建页面

index 页面,logs 页面和newPage 页面都在 pages 目录下。微信小程序中的每一个页面的【路径+页面名】都需要写在 app.json 的 pages 中,且 pages 中的第一个页面是小程序的首页。
每一个小程序页面是由同路径下同名的四个不同后缀文件的组成,如:index.js、index.wxml、index.wxss、index.json。.js后缀的文件是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件,.wxml后缀的文件是页面结构文件。

index 页面结构如下。

index.wxml:

<view class="container">
  <view  bindtap="bindViewTap" class="userinfo">
    <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
    <text class="userinfo-nickname">{{userInfo.nickName}}</text>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
  <view class="copyright">{{array[0].msg}}</view>
</view>

本例中使用了<view/>、<image/>、<text/>来搭建页面结构,绑定数据和交互处理函数。
index.js 是页面的脚本文件,在这个文件中我们可以监听并处理页面的生命周期函数、获取小程序实例,声明并处理数据,响应页面交互事件等。

index.js:

//获取应用实例
var app = getApp();
console.log(app.globalData.currData);
Page({
  data: {
    motto: 'Hello xhh',
    userInfo: {},
    array: [{msg: '版权所有,翻版必究'}, {msg: 'msg2'}]
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    console.log('onLoad')
    var that = this
    //调用应用实例的方法获取全局数据
    app.getUserInfo(function(userInfo){
      //更新数据
      that.setData({
        userInfo:userInfo
      })
    })
  },
  onReady: function () {
      console.log('onReady');
  },
  onShow: function () {
      console.log('onShow');
  },
  onHide: function () {
      console.log('onHide');
  },
  onUnload: function () {
      console.log('onUnload');
  }
})

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;
}
.copyright {
  text-align:center;
  font-size:0.8rem;
  color: blueviolet;
  margin-top: 120rpx;
}

页面的样式表是非必要的。当有页面样式表时,页面的样式表中的样式规则会层叠覆盖 app.wxss 中的样式规则。如果不指定页面的样式表,也可以在页面的结构文件中直接使用 app.wxss 中指定的样式规则。
index.json 是页面的配置文件:
页面的配置文件是非必要的。当有页面的配置文件时,配置项在该页面会覆盖 app.json 的 window 中相同的配置项。如果没有指定的页面配置文件,则在该页面直接使用 app.json 中的默认配置。

index.json:

{
    "backgroundColor":"#49CB5F"
}

logs 页面结构如下。

logs.wxml:

<view class="container log-list">
  <block wx:for="{{logs}}" wx:for-item="log" wx:key="*this">
    <text class="log-item">{{index + 1}}. {{log}}</text>
  </block>
</view>

logs 页面使用 <block/> 控制标签来组织代码,在 <block/> 上使用 wx:for 绑定 logs 数据,并将 logs 数据循环展开节点。

logs.js:

var util = require('../../utils/util.js');
var common = require('../../utils/common.js');

Page({
  data: {
    logs: [],
  },
  onLoad: function () {
    this.setData({
      logs: (wx.getStorageSync('logs') || []).map(function (log) {
        return util.formatTime(new Date(log))
      })
    })
  },
  onShow: function () {
      common.sayHello('xhh')
  },
  onShareAppMessage: function () {
    return {
      title: '自定义分享标题',
      desc: '自定义分享描述',
      path: '/page/user?id=123'
    }
  }
})

logs.wxss:

.log-list {
  display: flex;
  flex-direction: column;
  padding: 40rpx;
}
.log-item {
  margin: 10rpx;
}

logs.json:

{
    "navigationBarTitleText": "查看启动日志"
}

newPage 页面结构如下。

newPage.wxml:

<block wx:for-items="{{arrayList}}">
  <text> {{index}}: </text>
  <text> {{item}} </text>
  <view></view>
</block>

<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'view'}}"> VIEW </view>

<template name="staffName">
  <view>
    FirstName: {{firstName}}, LastName: {{lastName}}
  </view>
</template>
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>

<view bindtap="add"> 点我计数:{{count}} </view>

<button bindtap="changeName"> Click me! Change the data below </button>
<view style="margin-top:10rpx">{{obj.text}}</view>

<view class="section">
  <view class="section__title">日期选择器:</view>
  <picker mode="date" value="{{date}}" start="2015-09-01" end="2018-01-01" bindchange="bindDateChange">
    <view class="picker">
      <label>当前选择:</label>
      <input class="dateInput" value="{{date}}" />
    </view>
  </picker>
</view>

<view class="group">
  <block wx:for="{{iconSize}}">
    <icon type="success" size="{{item}}" />
  </block>
</view>
<view class="group">
  <block wx:for="{{iconType}}">
    <icon type="{{item}}" size="45" />
  </block>
</view>
<view class="group">
  <block wx:for="{{iconColor}}">
    <icon type="success" size="45" color="{{item}}" />
  </block>
</view>

<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" current="{{currentPage}}">
  <block wx:for-items="{{imgUrls}}">
    <swiper-item>
      <image src="{{item}}" class="slide-image" width="355" height="150" />
    </swiper-item>
  </block>
</swiper>
<button bindtap="changeIndicatorDots" class="btnStyle"> indicator-dots </button>
<button bindtap="changeAutoplay" class="btnStyle"> autoplay </button>
<button bindtap="nextPage" class="btnStyle"> next page </button>
<slider bindchange="intervalChange" show-value min="500" max="2000" /> interval
<slider bindchange="durationChange" show-value min="1000" max="10000" /> duration

<audio poster="{{poster}}" name="{{name}}" author="{{author}}" src="{{src}}" id="myAudio" controls loop></audio>
<button type="primary" class="btnStyle" bindtap="audioPlay">播放</button>
<button type="primary" class="btnStyle" bindtap="audioPause">暂停</button>
<button type="primary" class="btnStyle" bindtap="audio14">设置当前播放时间为14秒</button>
<button type="primary" class="btnStyle" bindtap="audioStart">回到开头</button>

<button type="primary" class="btnStyle" bindtap="makeCall">拨打电话</button>

<button type="primary" class="btnStyle" bindtap="sendAjax">发送请求</button>

<button type="primary" class="btnStyle" bindtap="checkMap">查看位置</button>

<canvas style="width: 300px; height: 200px;" canvas-id="firstCanvas"></canvas>

newPage.js:

Page({
  onReady: function (e) {
    // 使用 wx.createAudioContext 获取 audio 上下文 context
    this.audioCtx = wx.createAudioContext('myAudio');

    wx.showToast({
      title: '成功',
      icon: 'success',
      duration: 2000
    })

      // 使用 wx.createContext 获取绘图上下文 context
    var context = wx.createContext()

    context.setStrokeStyle("#00ff00")
    context.setLineWidth(5)
    context.rect(0, 0, 200, 200)
    context.stroke()
    context.setStrokeStyle("#ff0000")
    context.setLineWidth(2)
    context.moveTo(160, 100)
    context.arc(100, 100, 60, 0, 2 * Math.PI, true)
    context.moveTo(140, 100)
    context.arc(100, 100, 40, 0, Math.PI, false)
    context.moveTo(85, 80)
    context.arc(80, 80, 5, 0, 2 * Math.PI, true)
    context.moveTo(125, 80)
    context.arc(120, 80, 5, 0, 2 * Math.PI, true)
    context.stroke()

    // 调用 wx.drawCanvas,通过 canvasId 指定在哪张画布上绘制,通过 actions 指定绘制行为
    wx.drawCanvas({
      canvasId: 'firstCanvas',
      actions: context.getActions() // 获取绘图动作数组
    })

  },
  data: {
    arrayList: ['item1', 'item2', 'item3', 'item4', 'item5'],
    view: 'WEBVIEW',
    staffA: { firstName: 'Hulk', lastName: 'Hu' },
    staffB: { firstName: 'Shang', lastName: 'You' },
    staffC: { firstName: 'Gideon', lastName: 'Lin' },
    count: 1,
    obj: { text: 'data' },
    iconSize: [20, 30, 40, 50, 60, 70],
    iconColor: [
      'red', 'orange', 'yellow', 'green', 'rgb(0,255,255)', 'blue', 'purple'
    ],
    iconType: [
      'success', 'info', 'warn', 'waiting', 'safe_success', 'safe_warn',
      'success_circle', 'success_no_circle', 'waiting_circle', 'circle', 'download',
      'info_circle', 'cancel', 'search', 'clear'
    ],
    imgUrls: [
      'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
      'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
      'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
    ],
    indicatorDots: false,
    autoplay: false,
    interval: 5000, // 自动切换时间间隔
    duration: 1000, // 滑动动画时长
    currentPage: 1,
    poster: 'http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000',
    name: '此时此刻',
    author: '许巍',
    src: 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E06DCBDC9AB7C49FD713D632D313AC4858BACB8DDD29067D3C601481D36E62053BF8DFEAF74C0A5CCFADD6471160CAF3E6A&fromtag=46',

  },
  changeName: function (e) {
    if (this.data.obj.text == "data") {
      this.setData({
        obj: { text: 'changed data' }
      })
    } else {
      this.setData({
        obj: { text: 'data' }
      })
    }
    console.log(this.data.obj.text);
  },
  add: function (e) {
    this.setData({
      count: this.data.count + 1
    })
  },
  bindDateChange: function (e) {
    this.setData({
      date: e.detail.value
    })
    console.log(this.data.date);
  },
  changeIndicatorDots: function (e) {
    this.setData({
      indicatorDots: !this.data.indicatorDots
    })
  },
  changeAutoplay: function (e) {
    this.setData({
      autoplay: !this.data.autoplay
    })
  },
  intervalChange: function (e) {
    this.setData({
      interval: e.detail.value
    })
  },
  durationChange: function (e) {
    this.setData({
      duration: e.detail.value
    })
  },
  nextPage: function (e) {
    var temp = this.data.currentPage + 1;
    if (temp >= 3) {
      temp = 0;
    }
    this.setData({
      currentPage: temp
    })
  },
  audioPlay: function () {
    this.audioCtx.play()
  },
  audioPause: function () {
    this.audioCtx.pause()
  },
  audio14: function () {
    this.audioCtx.seek(14)
  },
  audioStart: function () {
    this.audioCtx.seek(0)
  },
  makeCall: function () {
    wx.makePhoneCall({
      phoneNumber: '15151547384'
    })
  },
  sendAjax: function () {
    wx.request({
      url: 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN',
      data: {
        "path": "pages/index?query=1",
        "width": 430
      },
      header: {
        'content-type': 'application/json'
      },
      method: 'POST',
      success: function (res) {
        console.log(res.data);
      },
      fail: function () {

      },
      complete: function () {

      }
    })
  },
  checkMap: function () {
    wx.getLocation({
      type: 'gcj02', //返回可以用于wx.openLocation的经纬度
      success: function (res) {
        var latitude = res.latitude
        var longitude = res.longitude
        wx.openLocation({
          latitude: latitude,
          longitude: longitude,
          scale: 28
        })
      }
    })
  }
})

newPage.wxss:

.dateInput {
    display:inline-block;
    vertical-align: -8px;
    border: 1px solid darkslategray;
}
.section .section__title {
    color: blueviolet;
}
.slide-image{
    width: 100%;
    padding: 40rpx 0; 
}
.btnStyle {
    width:400rpx;
    height:100rpx;
    margin-top:40rpx;
    margin-bottom: 10rpx;
}

newPage.json:

{
    "navigationBarTitleText": "newPage"
}

文件目录结构如下:
图片描述

5.配置

app.json 配置项列表:
图片描述

pages:
接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面。小程序中新增/减少页面,都需要对 pages 数组进行修改。
文件名不需要写文件后缀,因为框架会自动去寻找路径.json,.js,.wxml,.wxss的四个文件进行整合。
window:
用于设置小程序的状态栏、导航条、标题、窗口背景色。
图片描述

tabBar:
如果我们的小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),那么我们可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
Tip: 通过页面跳转(wx.navigateTo)或者页面重定向(wx.redirectTo)所到达的页面,即使它是定义在 tabBar 配置中的页面,也不会显示底部的 tab 栏。
tabBar 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
图片描述

其中 list 接受一个数组,数组中的每个项都是一个对象,其属性值如下:
图片描述
networkTimeout:
可以设置各种网络请求的超时时间。
图片描述

debug:
可以在开发者工具中开启 debug 模式,在开发者工具的控制台面板,调试信息以 info 的形式给出,其信息有Page的注册,页面路由,数据更新,事件触发 。 可以帮助开发者快速定位一些常见的问题。
page.json:
每一个小程序页面也可以使用.json文件来对本页面的窗口表现进行配置。 页面的配置比app.json全局配置简单得多,只是设置 app.json 中的 window 配置项的内容,页面中配置项会覆盖 app.json 的 window 中相同的配置项。
页面的.json只能设置 window 相关的配置项,以决定本页面的窗口表现,所以无需写 window 这个键。
图片描述

6.逻辑层

(1) 注册程序:
App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。
object参数说明:
图片描述

前台、后台定义: 当用户点击左上角关闭,或者按了设备 Home 键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。
只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。
getApp()
我们提供了全局的 getApp() 函数,可以获取到小程序实例。
// other.js

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

注意:
App() 必须在 app.js 中注册,且不能注册多个。
不要在定义于 App() 内的函数中调用 getApp() ,使用 this 就可以拿到 app 实例。
不要在 onLaunch 的时候调用 getCurrentPage(),此时 page 还没有生成。
通过 getApp() 获取实例之后,不要私自调用生命周期函数。
(2) 注册页面:
Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。
object 参数说明:
图片描述

初始化数据
初始化数据将作为页面的第一次渲染。data 将会以 JSON 的形式由逻辑层传至渲染层,所以其数据必须是可以转成 JSON 的格式:字符串,数字,布尔值,对象,数组。
渲染层可以通过 WXML 对数据进行绑定。
示例代码:

<view>{{text}}</view>
<view>{{array[0].msg}}</view>

Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

生命周期函数:

onLoad: 页面加载
一个页面只会调用一次。
接收页面参数可以获取wx.navigateTo和wx.redirectTo及<navigator/>中的 query。
onShow: 页面显示
每次打开页面都会调用一次。
onReady: 页面初次渲染完成
一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。详见生命周期
onHide: 页面隐藏
当navigateTo或底部tab切换时调用。
onUnload: 页面卸载
当redirectTo或navigateBack的时候调用。
页面相关事件处理函数
onPullDownRefresh: 下拉刷新
监听用户下拉刷新事件。
需要在config的window选项中开启enablePullDownRefresh。
当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
onShareAppMessage: 用户分享
只有定义了此事件处理函数,右上角菜单才会显示“分享”按钮
用户点击分享按钮的时候会调用
此事件需要 return 一个 Object,用于自定义分享内容。

自定义分享字段:
图片描述

示例代码:

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

事件处理函数
除了初始化数据和生命周期函数,Page 中还可以定义一些特殊的函数:事件处理函数。在渲染层可以在组件中加入事件绑定,当达到触发事件时,就会执行 Page 中定义的事件处理函数。
示例代码:

<view bindtap="viewTap"> click me </view>

Page({
  viewTap: function() {
    console.log('view tap')
  }
})

setData() 参数格式:
接受一个对象,以 key,value 的形式表示将 this.data 中的 key 对应的值改变成 value。
其中 key 可以非常灵活,以数据路径的形式给出,如 array[2].message,a.b.c.d,并且不需要在 this.data 中预先定义。
示例代码:

<!--index.wxml-->
<view>{{text}}</view>
<button bindtap="changeText"> Change normal data </button>
<view>{{array[0].text}}</view>
<button bindtap="changeItemInArray"> Change Array data </button>
<view>{{object.text}}</view>
<button bindtap="changeItemInObject"> Change Object data </button>
<view>{{newField.text}}</view>
<button bindtap="addNewField"> Add new data </button>

//index.js
Page({
  data: {
    text: 'init data',
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data'  // bad, it can not work
    this.setData({
      text: 'changed data'
    })
  },
  changeItemInArray: function() {
    // you can use this way to modify a danamic data path
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }
})

(3) 模块化:
模块化
我们可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。

需要注意的是:

exports 是 module.exports 的一个引用,因此在模块里边随意更改 exports 的指向会造成未知的错误。所以我们更推荐开发者采用 module.exports 来暴露模块接口,除非你已经清晰知道这两者的关系。
小程序目前不支持直接引入 node_modules , 开发者需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中。
// common.js

function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

​在需要使用这些模块的文件中,使用 require(path) 将公共代码引入

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

7.视图层

(1) WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
用以下一些简单的例子来看看 WXML 具有什么能力:
数据绑定:

<!--wxml-->
<view> {{message}} </view>
// page.js
Page({
  data: {
    message: 'Hello MINA!'
  }
})

列表渲染

<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>
// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5]
  }
})

条件渲染

<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
  data: {
    view: 'MINA'
  }
})

模板

<!--wxml-->
<template name="staffName">
  <view>
    FirstName: {{firstName}}, LastName: {{lastName}}
  </view>
</template>

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

事件

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

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

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

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

内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。

<view style="color:{{color}};" />

class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。

<view class="normal_view" />

选择器
目前支持的选择器有:
图片描述

全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

8.组件

(1)视图容器:

view
scroll-view
swiper

(2)基础内容:

icon
text
progress

(3)表单组件:

button
checkbox
form
input 
label
picker
picker-view
radio
slider
switch
textarea

(4)导航组件:

navigator

(5)媒体组件:

audio
image
video

(6)地图:

map

(7)画布:

canvas

(8)客服会话:

contact-button

9.API

(1)网络
(2)媒体
(3)文件
(4)数据缓存
(5)位置
(6)设备
(7)界面
(8)开放接口


园中桥
49 声望0 粉丝

愿你眼中总有光芒,活成自己想要的模样。


下一篇 »
es6要点