微信小程序理解进阶
1 data
data 是页面第一次渲染使用的初始数据。页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。
wxml里的代码:
<view>{% raw %}{{% endraw %}{text}}view>
<view>{% raw %}{{% endraw %}{array[0].msg}}view>
js里的data模型:
Page({data: {text: 'init data',array: [{msg: '1'}, {msg: '2'}]}
})
2 生命周期函数
-
onLoad(Object query)
页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。 -
onShow()
页面显示/切入前台时触发。 -
onReady()
页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。 -
onHide()
页面隐藏/切入后台时触发。 如 navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。 -
onUnload()
页面卸载时触发。如redirectTo或navigateBack到其他页面时。
需要注意的是:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady之后进行。
可以通过一个简单的例子来测试执行顺序:
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {console.log("页面加载时触发")},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {console.log("onReady:监听页面初次渲染完成");},/*** 生命周期函数--监听页面显示*/onShow: function () {console.log("onShow:页面显示时触发");},/*** 生命周期函数--监听页面隐藏*/onHide: function () {console.log("页面隐藏时触发");},/*** 生命周期函数--监听页面卸载*/onUnload: function () {console.log("页面卸载时触发");}
})
3 模块化
官网地址:https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/module.html
uitls文件用来存放一些js文件,这些js文件里包含了一些用在全局的js共用方法等,通常也被工具包,我们根据项目需要在里面添加工具类,将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。
举例说明:
- 第一步:我们在uitls里自顶一个commen.js文件,并书写两个方法:

- 第二步:在一个页面里来使用这两个方法,在使用这个模块方法之前,需要使用使用
require(path)将公共代码引入,比如我们可以在pages/notice/notice.js 里Page({})里进行测试。
// pages/notice/notice.js
var commonjs=require("../../utils/common.js")Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {commonjs.fn1("hello!")},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {commonjs.fn2("bye!")}
})
页面的控制台里显示:

4 全局变量的使用
全局js配置文件,小程序加载时先运行这个文件,这里定义的变量为全局变量,可在页面内通过 getApp() 获取,现在通过一个例子来进行说明:
第一步:在app.js 里的globalData里定义一个空变量

第二步:在pages/notice/notice.js 里书写代码
// pages/notice/notice.js
var commonjs=require("../../utils/common.js")
var app=getApp();
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {commonjs.fn1("hello!");app.globalData.appName="完美校园";},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {commonjs.fn2("bye!");console.log(app.globalData.appName);},/*** 生命周期函数--监听页面显示*/onShow: function () {}
})
5. 数据绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来,用法和Vuejs非常相似:
5.1 内容
<view>{% raw %}{{% endraw %}{ message }}view>
Page({data: {message: 'Hello world!'}
})
5.2 组件属性(需要在双引号之内)
<view id="item-{% raw %}{{% endraw %}{id}}">view>
Page({data: {id: 0}
})
5.3 控制属性(需要在双引号之内)
<view wx:if="{% raw %}{{% endraw %}{condition}}">view>
Page({data: {condition: true}
})
5.4 关键字(需要在双引号之内)
true:boolean 类型的 true,代表真值。
false: boolean 类型的 false,代表假值。
<checkbox checked="{% raw %}{{% endraw %}{false}}">checkbox>
特别注意:不要直接写 checked=“false”,其计算结果是一个字符串,转成 boolean 类型后代表真值。
5.5 运算
可以在{ { } }内进行简单的运算,支持的有如下几种方式:
- 三元运算
<view hidden="{% raw %}{{% endraw %}{flag ? true : false}}">Hiddenview>
- 算术运算
<view>{% raw %}{{% endraw %}{a + b}} + {% raw %}{{% endraw %}{c}} + dview>
Page({data: {a: 1,b: 2,c: 3}
})
view中的内容为 3 + 3 + d。
- 逻辑判断
<view wx:if="{% raw %}{{% endraw %}{length > 5}}">view>
- 字符串运算
<view>{% raw %}{{% endraw %}{"hello" + name}}view>
Page({data: {name: 'MINA'}
})
- 数据路径运算
<view>{% raw %}{{% endraw %}{object.key}} {% raw %}{{% endraw %}{array[0]}}view>
Page({data: {object: {key: 'Hello '},array: ['MINA']}
})
- 组合
也可以在 Mustache 内直接进行组合,构成新的对象或者数组。
- 数组
<view wx:for="{% raw %}{{% endraw %}{[zero, 1, 2, 3, 4]}}">{% raw %}{{% endraw %}{item}}view>
Page({data: {zero: 0}
})
最终组合成数组[0, 1, 2, 3, 4]。
- 对象
<template is="objectCombine" data="{% raw %}{{% endraw %}{for: a, bar: b}}">template>
Page({data: {a: 1,b: 2}
})
最终组合成的对象是{for: 1, bar: 2}
也可以用扩展运算符 ... 来将一个对象展开
<template is="objectCombine" data="{% raw %}{{% endraw %}{...obj1, ...obj2, e: 5}}">template>
Page({data: {obj1: {a: 1,b: 2},obj2: {c: 3,d: 4}}
})
最终组合成的对象是 {a: 1, b: 2, c: 3, d: 4, e: 5}。
如果对象的 key 和 value 相同,也可以间接地表达。
<template is="objectCombine" data="{% raw %}{{% endraw %}{foo, bar}}">template>
Page({data: {foo: 'my-foo',bar: 'my-bar'}
})
最终组合成的对象是 {foo: ‘my-foo’, bar:‘my-bar’}。
注意:上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面,如:
<template is="objectCombine" data="{% raw %}{{% endraw %}{...obj1, ...obj2, a, c: 6}}">template>
Page({data: {obj1: {a: 1,b: 2},obj2: {b: 3,c: 4},a: 5}
})
最终组合成的对象是 {a: 5, b: 3, c: 6}。
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
<view wx:for="{% raw %}{{% endraw %}{[1,2,3]}} ">{% raw %}{{% endraw %}{item}}
view>
等同于
<view wx:for="{% raw %}{{% endraw %}{[1,2,3] + ' '}}">{% raw %}{{% endraw %}{item}}
view>
6. 条件渲染
- wx:if
在框架中,使用 wx:if="{% raw %}{{% endraw %}{condition}}" 来判断是否需要渲染该代码块:
<view wx:if="{% raw %}{{% endraw %}{condition}}">Trueview>
- 也可以用 wx:elif 和 wx:else 来添加一个 else 块:
<view wx:if="{% raw %}{{% endraw %}{length > 5}}">1view>
<view wx:elif="{% raw %}{{% endraw %}{length > 2}}">2view>
<view wx:else>3view>
- block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{% raw %}{{% endraw %}{true}}"><view>view1view><view>view2view>
block>
注意: 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性
7. 列表渲染
7.1 wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<view wx:for="{% raw %}{{% endraw %}{array}}">{% raw %}{{% endraw %}{index}}: {% raw %}{{% endraw %}{item.message}}
view>
Page({data: {array: [{message: 'foo',}, {message: 'bar'}]}
})
使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:
<view wx:for="{% raw %}{{% endraw %}{array}}" wx:for-index="idx" wx:for-item="itemName">{% raw %}{{% endraw %}{idx}}: {% raw %}{{% endraw %}{itemName.message}}
view>
wx:for 也可以嵌套,下边是一个九九乘法表
<view wx:for="{% raw %}{{% endraw %}{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i"><view wx:for="{% raw %}{{% endraw %}{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j"><view wx:if="{% raw %}{{% endraw %}{i <= j}}">{% raw %}{{% endraw %}{i}} * {% raw %}{{% endraw %}{j}} = {% raw %}{{% endraw %}{i * j}}view>view>
view>
7.2 block wx:for
类似 block wx:if,也可以将 wx:for 用在标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{% raw %}{{% endraw %}{[1, 2, 3]}}"><view>{% raw %}{{% endraw %}{index}}:view><view>{% raw %}{{% endraw %}{item}}view>
block>
7.3 wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 中的输入内容,的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字
*this代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
示例代码:
<switch wx:for="{% raw %}{{% endraw %}{objectArray}}" wx:key="unique" style="display: block;">{% raw %}{{% endraw %}{item.id}}
switch>
<button bindtap="switch">Switchbutton>
<button bindtap="addToFront">Add to the frontbutton><switch wx:for="{% raw %}{{% endraw %}{numberArray}}" wx:key="*this" style="display: block;">{% raw %}{{% endraw %}{item}}
switch>
<button bindtap="addNumberToFront">Add to the front</button>
Page({data: {objectArray: [{id: 5, unique: 'unique_5'},{id: 4, unique: 'unique_4'},{id: 3, unique: 'unique_3'},{id: 2, unique: 'unique_2'},{id: 1, unique: 'unique_1'},{id: 0, unique: 'unique_0'},],numberArray: [1, 2, 3, 4]},switch(e) {const length = this.data.objectArray.lengthfor (let i = 0; i < length; ++i) {const x = Math.floor(Math.random() * length)const y = Math.floor(Math.random() * length)const temp = this.data.objectArray[x]this.data.objectArray[x] = this.data.objectArray[y]this.data.objectArray[y] = temp}this.setData({objectArray: this.data.objectArray})},addToFront(e) {const length = this.data.objectArray.lengththis.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)this.setData({objectArray: this.data.objectArray})},addNumberToFront(e) {this.data.numberArray = [this.data.numberArray.length + 1].concat(this.data.numberArray)this.setData({numberArray: this.data.numberArray})}
})
注意:
当 wx:for 的值为字符串时,会将字符串解析成字符串数组
<view wx:for="array">{% raw %}{{% endraw %}{item}}
view>
等同于
<view wx:for="{% raw %}{{% endraw %}{['a','r','r','a','y']}}">{% raw %}{{% endraw %}{item}}
view>
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
<view wx:for="{% raw %}{{% endraw %}{[1,2,3]}} ">{% raw %}{{% endraw %}{item}}
view>
等同于
<view wx:for="{% raw %}{{% endraw %}{[1,2,3] + ' '}}">{% raw %}{{% endraw %}{item}}
view>
8. 事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
在小程序中,用户使用的最多的操作几种事件分别是点击、拖动、双击、输入
【举例说明】:
- 在组件中绑定一个事件处理函数。
如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="微信" bindtap="tapName">点我view>
- 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({tapName(event) {console.log(event)}
})
- 可以看到log出来的信息大致如下:
{"type": "tap","timeStamp": 895,"target": {"id": "tapTest","dataset": {"hi": "WeChat"}},"currentTarget": {"id": "tapTest","dataset": {"hi": "微信"}},"detail": {"x": 53,"y": 14},"touches": [{"identifier": 0,"pageX": 53,"pageY": 14,"clientX": 53,"clientY": 14}],"changedTouches": [{"identifier": 0,"pageX": 53,"pageY": 14,"clientX": 53,"clientY": 14}]
}
9. 和后台数据进行交互
官网地址:https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html
在index.wxml 文件中添加两个组件
<view>{% raw %}{{% endraw %}{ msg }}view>
<button bindtap="bindViewTap">点击我button>
在js文件里书写bindViewTap方法
Page({data: {},//事件处理函数bindViewTap1: function () {var _this = this;var msgFromBack = "";wx.request({url: 'http://localhost:3004/index', // 仅为示例,并非真实的接口地址data: {},header: {'content-type': 'application/json' // 默认值},success(res) {console.log(res.data);//查看官方api方法msgFromBack = res.data.comments;_this.setData(res.data);//统一赋值_this.setData({msg: msgFromBack});//单属性赋值}})}
})
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
