小程序开发框架将我们需要完成的编码,划分成了两种类型的编码:逻辑编码(由JavaScript完成,业务数据供给界面事件处理),界面编码(页面结构WXML,页面样式WXSS,展示逻辑层的数据).
小程序开发中使用到的JavaScript同常规网页开发所使用的JavaScript有所差异,在小程序的开发之中,有很多的.js文件,他们都属于页面的逻辑层,我们知道程序一旦启动就会去执行app.js文件中的代码,我们可以使用console.log()方法来验证.
小程序不是运行在浏览器中,所以没有BOM和DOM对象,但是在小程序只用存在一些特有的全局成员:
1 //app.js
2
3 console.log("==============================");
4 //自定义逻辑代码
5 //1.小程序不是运行在浏览器中,所以没有BOM和DOM对象
6 console.log(window); //在小程序中无法获取到BOM中定义的成员
7 console.log(document); //无法获取到DOM中定义的成员
8 //2.小程序的JS有一些额外的成员(全局)
9 //App 方法:用于定义应用程序实例对象
10 //Page方法:用于定义页面对象
11 //getApp方法:用于获取全局应用程序对象,每个小程序都由唯一的应用程序实例
12 //getCurrentPages:用于获取当前页面的调用栈
13 //wx对象: 用来提供核心api
14 console.log(wx);
15 //3.小程序的JS是支持CommonJS规范(用于约定这些文件与文件之间是如何组织,相互之间协同的)的
16 //通过module 和 require来传递通用方法
17 const foo = require("./utils/foo.js");
18 foo.say("world");
19 console.log("==============================");
20 var obj = {
21 onLaunch: function() {
22 // 展示本地存储能力
23 var logs = wx.getStorageSync('logs') || []
24 logs.unshift(Date.now())
25 wx.setStorageSync('logs', logs)
26
27 // 登录
28 wx.login({
29 success: res => {
30 // 发送 res.code 到后台换取 openId, sessionKey, unionId
31 }
32 })
33 // 获取用户信息
34 wx.getSetting({
35 success: res => {
36 if (res.authSetting['scope.userInfo']) {
37 // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
38 wx.getUserInfo({
39 success: res => {
40 // 可以将 res 发送给后台解码出 unionId
41 this.globalData.userInfo = res.userInfo
42
43 // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
44 // 所以此处加入 callback 以防止这种情况
45 if (this.userInfoReadyCallback) {
46 this.userInfoReadyCallback(res)
47 }
48 }
49 })
50 }
51 }
52 })
53 },
54 globalData: {
55 userInfo: null
56 },
57 //自定义成员方法
58 foo: function() {
59 console.log("自定义成员方法");
60 }
61 };
62 //调用了一个APP方法(全局方法)
63 App(obj);
64 //调用App方法的作用是用来创建应用程序实例对象
65 //定义应用程序的生命周期事件
1 function say(msg){
2 console.log("hello " + msg);
3 }
4
5 // 导出say()方法
6 module.exports = {
7 say: say
8 }
9 //在标准的COmmonJS规范中还支持exports.say 来导出,但是在小程序当中是不支持的,只支持module.exports
1 //index.js
2 //获取应用实例
3 //完成页面的逻辑,包括功能的实现
4 const app = getApp()
5
6 Page({
7 data: {
8 motto: 'Hello World',
9 userInfo: {},
10 hasUserInfo: false,
11 canIUse: wx.canIUse('button.open-type.getUserInfo')
12 },
13 //事件处理函数
14 bindViewTap: function() {
15 wx.navigateTo({
16 url: '../logs/logs'
17 })
18 },
19 onLoad: function () {
20 if (app.globalData.userInfo) {
21 this.setData({
22 userInfo: app.globalData.userInfo,
23 hasUserInfo: true
24 })
25 } else if (this.data.canIUse){
26 // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
27 // 所以此处加入 callback 以防止这种情况
28 app.userInfoReadyCallback = res => {
29 this.setData({
30 userInfo: res.userInfo,
31 hasUserInfo: true
32 })
33 }
34 } else {
35 // 在没有 open-type=getUserInfo 版本的兼容处理
36 wx.getUserInfo({
37 success: res => {
38 app.globalData.userInfo = res.userInfo
39 this.setData({
40 userInfo: res.userInfo,
41 hasUserInfo: true
42 })
43 }
44 })
45 }
46 },
47 getUserInfo: function(e) {
48 console.log(e)
49 app.globalData.userInfo = e.detail.userInfo
50 this.setData({
51 userInfo: e.detail.userInfo,
52 hasUserInfo: true
53 })
54 },
55 onShow: function () {
56 //在每次该界面唤醒时,获取当前页面的调用栈:
57 console.log(getCurrentPages());
58 console.log("当前调用栈中的页面数量: " + getCurrentPages());
59 }
60
61 })
1 // pages/demo/demo.js
2
3 //获取当前小程序对象实例
4 var app = getApp();
5 Page({
6
7 /**
8 * 页面的初始数据
9 */
10 data: {
11
12 },
13
14 /**
15 * 生命周期函数--监听页面加载
16 */
17 onLoad: function (options) {
18 app.foo();
19
20 },
21
22 /**
23 * 生命周期函数--监听页面初次渲染完成
24 */
25 onReady: function () {
26
27 },
28
29 /**
30 * 生命周期函数--监听页面显示
31 */
32 onShow: function () {
33 //在每次该界面唤醒时,获取当前页面的调用栈:
34 console.log(getCurrentPages());
35 console.log("当前调用栈中的页面数量: " + getCurrentPages());
36 console.log(getCurrentPages()[getCurrentPages().length - 1] == this);
37 },
38
39 /**
40 * 生命周期函数--监听页面隐藏
41 */
42 onHide: function () {
43
44 },
45
46 /**
47 * 生命周期函数--监听页面卸载
48 */
49 onUnload: function () {
50
51 },
52
53 /**
54 * 页面相关事件处理函数--监听用户下拉动作
55 */
56 onPullDownRefresh: function () {
57
58 },
59
60 /**
61 * 页面上拉触底事件的处理函数
62 */
63 onReachBottom: function () {
64
65 },
66
67 /**
68 * 用户点击右上角分享
69 */
70 onShareAppMessage: function () {
71
72 }
73 })
在程序的开发过程中,界面层提供一种模板机制,可以借助一种特殊的语法来完成数据的绑定,将动态的数据绑定到模板当中,最近将嵌入过后的数据显示到界面中,小程序中使用的是Mustache 语法(双大括号)语法:
1
2
3
7
8 {{ message }}
9 {{ person.name }} : {{ person.age }}
10
1 // pages/demo/demo.js
2
3 Page({
4 //为页面提供数据,界面和逻辑之间的桥梁
5 data:{
6 message:"hello world",
7 person:{
8 name: "张三",
9 age:25
10 }
11 }
12 })
--数据绑定语法补充,除了在页面标签的内部我们会使用Mustache语法进行输出,在标签的内部,我们也可以使用Mustache语法:
1
2
3
7
8 {{ message }}
9 {{ person.name }} : {{ person.age }}
10
14
15
16 {{ 'hello' }}
17 {{ 111 }}
18 {{ 111 + 222 }}
19 {{ 111 < 222 ? 'yes' : 'no' }}
20 {{ true }}
21
24 复选框1
25 复选框2
26
在逻辑层中,很多的情况下都会是一个数组类型的数据(列表数据),那么此时在我们的界面层中就需要使用到列表渲染:
1
4 复选框1
5 复选框2
6
7
8
20
30
31 {{ bbb + 1 }}:
32
33 {{ item.name }} {{ aaa.name }}
34
35
36
37
38
39
40 {{ i }} * {{ j }} = {{ i * j }}
41
42
43
44
45
1
3
1 buttonTapHandle: function(e){
2 console.log("点击按钮打印此条.");
3 // console.dir()将一个对象以树状的形式打印到控制台,便于我们调试复杂对象
4 console.dir(e);
5 }
1
4
5
6
1 innerHandler: function(){
2 console.log("触发内部事件");
3 },
4 outerHandler: function(){
5 console.log("触发外部事件");
6 }
1
8
1 handleWithParm(e){
2 console.log(e); //获取当前的点击元素
3 console.log(e.target.dataset); //获取元素上所有data-[xxx]属性的集合
4 }
1
4
5
6 {{ inputMessage }}
7
1 inputHandler: function(e) {
2 //e.detail.value 获取到当前输入的值
3 console.log(e.detail.value);
4 //小程序中的数据绑定,本质上是一次绑定,在绑定完成之后,并不会去监视数据的变化.如果想要得到此次的变化,那么就需要使用setData的方法进行改变
5 //setData是用来改变data数据的,与直接赋值区别在于setData可以通知界面作出变化,而直接赋值的话没有办法实现这一点(早期的JS无法实现)
6 this.setData({
7 inputMessage: "您输入的内容: " + e.detail.value
8 })
9 console.log(this.data.message);
10 }
1
2
3
4
6
8
9
10
11
12
13
1 // pages/login/login.js
2 /* 实现登录界面
3 1. 设计数据的结构(data属性)
4 2. 将数据绑定到指定的元素上
5 */
6 Page({
7 data: {
8 username: "",
9 password: ""
10 },
11 //用于处理登录按钮点击的事件
12 buttonLogin: function() {
13 console.log("执行登录事件");
14 },
15 //用于处理注册按钮点击的事件
16 buttonRegister: function() {
17 //1. 首先需要知道用户输入了什么
18 console.log(this.data.username + " " + this.data.password);
19 //2. 根据用户输入的值去判断
20 //3. 根据判断的结果做出响应
21 console.log("执行注册事件");
22 },
23 //用户输入用户名
24 usernameChangeHandler: function(e) {
25 this.setData({
26 username: e.detail.value
27 })
28 },
29 //用户输入密码
30 passwordChangeHandler: function(e) {
31 this.setData({
32 password: e.detail.value
33 })
34 }
35 })
如我在我们的代码之中为每一个input标签都增加一个事件绑定函数,那么在我们的代码之中,将会存在很多的重复代码,为了避免这样的的情况,我们可以抽象共同的事件处理函数:
1
2
3
4
6
8
9
10
11
12
13
1 // pages/login/login.js
2 /* 实现登录界面
3 1. 设计数据的结构(data属性)
4 2. 将数据绑定到指定的元素上
5 */
6 Page({
7 data: {
8 username: "",
9 password: ""
10 },
11 //用于处理登录按钮点击的事件
12 buttonLogin: function() {
13 console.log(this.data.username + " " + this.data.password);
14 console.log("执行登录事件");
15 },
16 //用于处理注册按钮点击的事件
17 buttonRegister: function() {
18 //1. 首先需要知道用户输入了什么
19 console.log(this.data.username + " " + this.data.password);
20 //2. 根据用户输入的值去判断
21 //3. 根据判断的结果做出响应
22 console.log("执行注册事件");
23 },
24 //用户输入用户名
25 // usernameChangeHandler: function(e) {
26 // this.setData({
27 // username: e.detail.value
28 // })
29 // },
30 //用户输入密码
31 // passwordChangeHandler: function(e) {
32 // this.setData({
33 // password: e.detail.value
34 // }),
35 // console.log(e);
36 // }
37 //抽象上述两个方法,完成事件
38 inputChangeHandler: function(e) {
39 var key = e.target.dataset.name;
40 var value = e.detail.value;
41 var changed = {};
42 changed[key] = value;
43 this.setData(changed);
44 }
45 })
--除此之外,我们还可以使用表单的方式来进行数据的接收,这样可以免除这一些列复杂的操作:
1
2
4
6
7
8
9
10
1 //使用表单提交的方式来完成数据接收
2 loginSubmit: function(e){
3 console.log(e.detail.value);
4 }
1
2
3
4
5 面板中显示的内容
6 面板中显示的内容
7 面板中显示的内容
8
9
11
12 面板中显示的内容1
13 面板中显示的内容2
14 面板中显示的内容3
15
16
19
20 面板中显示的内容4
21 面板中显示的内容5
22 面板中显示的内容6
23
24
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。即将所有设备都使用rpx为750设置为撑满屏幕宽度.
1 .demo {
2 width: 750rpx;
3 height: 200px;
4 background-color: red;
5 }
原文作者:灰色天空_graySky
原文链接:https://www.cnblogs.com/skykuqi/p/11735404.html