第5章JavaScript基础
JavaScript是小程序逻辑层的编程语言,JavaScript代码大约占小程序代码量的一半,学好JavaScript是学好小程序开发的关键。
本章主要目标
熟练掌握JavaScript语法格式;
熟练掌握JavaScript变量、数据类型、运算符、函数等基本概念;
熟练掌握小程序事件函数中this和that的使用;
熟练掌握JavaScript在小程序中的交互场景应用。
5.1JavaScript简介
JavaScript是一种轻量、解释型、支持面向对象编程风格的脚本语言,它是一种直译式、动态类型、弱类型以及基于原型的语言。JavaScript语言不仅可用于Web前端开发,也广泛用于后端开发和智能手机开发。JavaScript的标准是ECMAScript。2015年6月17日,ECMA国际组织发布了ECMAScript 的第六版,该版本正式名称为 ECMAScript 2015,但通常被称为ECMAScript 6 或者ES6。
JavaScript具有以下特性:
JavaScript是一种基于对象的脚本语言,它不仅能够创建对象,而且可以使用对象;
JavaScript是一种轻量级的编程语言;
JavaScript是可插入HTML页面的编程代码;
JavaScript插入HTML页面后,可由现在所有的浏览器执行。
正是由于JavaScript易学易用的特性,使得它在最近几年应用广泛,获得了编程界的好评,同时出现了大量基于JavaScript的开源项目。如今JavaScript不仅可以实现前端的动态交互功能,而且可以运行于后端,为用户提供高性能的后端服务。在微信小程序中,JavaScript是小程序逻辑层使用的唯一开发语言,这也客观反映出JavaScript的强大,因此学好JavaScript对实现前端的交互功能非常重要。
在iOS系统中,小程序的JavaScript代码是运行在JavaScriptCore中,然后由WKWebView来渲染。
在安卓系统中,小程序的JavaScript代码是由X5 JS core来解析,由X5内核渲染。
在微信开发者工具(IDE)中,小程序的JavaScript代码是运行在nw.js中,由Chrome WebView来渲染。其中,nw.js是基于Chromium和Node.js运行的,封装了Webkit内核和Node.js,提供了桌面应用的运行环境,让在浏览器运行的程序也可以在桌面端运行。
这3个运行环境(iOS、安卓和微信开发者工具)使用的ECMA标准是不一样的,目前ECMAScript(简称ES)有8个版本,小程序使用的是ES5和ES6标准。但截至目前,iOS 8和iOS 9并没有完全兼容到ES6的标准,即ES6中的一些语法和关键字不被兼容,所以经常会发现,在微信开发者工具里和手机真机上的代码表现不一致,对此可以用微信开发者工具里的远程调试功能,在真机上进行调试。
5.2JavaScript基础语法
本节将介绍JavaScript的基础语法,包括变量、数据类型、运算符、逻辑控制语句等。
5.2.1变量
变量是存储信息的容器,所有JavaScript变量必须以唯一的名称标识,标识称为变量名。定义变量名称的规则为: 名称可包含字母、数字、下画线; 名称必须以字母开头,对大小写敏感(x和X是不同的变量); JavaScript的关键词不能作为变量名称。
示例代码:
var a = 1;//声明变量a并且赋值为数字1
var b = "abc";//声明变量a并且赋值为字符串abc
如上述代码所示,注释是指编程中用于解释说明的部分,用于提高代码的可读性。 JavaScript支持单行注释和多行注释。
单行注释用//标注;
多行注释用/*…*/标注。
5.2.2数据类型
JavaScript变量能够保存多种数据类型: 字符串、数字、逻辑值、数组、对象。本节将逐一介绍。
1. 字符串(String)类型
字符串用于存储一系列字符,使用单引号或双引号包裹字符串的内容。
示例代码:
var hello = "Hello xiaochengxu";
var hello = 'Hello xiaochengxu';
无论是单引号还是双引号,都需要成对出现,不能出现不一致现象,否则在编译时会报错。
2. 数字(Number)类型
JavaScript只有一种数字类型,数值后面的小数点可省略,用科学记数法能够表示极大值和极小值。
var x1 = 1.00;//带小数点
var x2 = 1;//不带小数点
var m = 123e5;//12300000
var n = 123e-5;//0.00123
3. 布尔(Boolean)类型
布尔(逻辑)类型只有两个值: true和false,在使用布尔值时,不能出现"false"或"true",否则会被解析为字符串。
示例代码:
var x = true;
var y = false;
变量x和变量y都是布尔类型,如果按照下面写法:
var x = "true";
var y = "false";
变量x和变量y都是字符串类型,字符串里面的内容分别为true和false。
4. 数组类型
JavaScript中的数组用方括号书写,数组中的元素由逗号分隔。
示例代码:
var list = ["a", "b", "c", "d", "e", "f"];
上述代码定义一个数组,数组名为list,数组中包含6个元素。数组的索引index从0到数组的个数减1,通过索引值可以取得数组中的元素。例如list[2]可以取得数组中的第3个元素。数组中包含一些常用的方法,在微信小程序中常用的Array对象方法如表5.1所示。
表5.1Array对象方法
方法名说明
pop() 删除并返回数组的最后一个元素
push()向数组的末尾添加一个或更多元素,并返回新的长度
reverse()颠倒数组中元素的顺序
shift()删除并返回数组的第一个元素
slice()从某个已有的数组返回选定的元素
sort() 对数组的元素进行排序
splice() 删除元素,并向数组添加新元素
toString() 把数组转换为字符串,并返回结果
unshift()向数组的开头添加一个或更多元素,并返回新的长度
以表5.1中的push()方法为例,示例代码如下:
var fruits = ["Apple", "Banana", "Lemon", "Grape"];
fruits.push("Cherry");
for (var i = 1; i < fruits.length; i++) {
console.log(fruits[i]);
}
上述代码执行完以后,会在Console控制台输出“Apple,Banana,Lemon,Grape,Cherry”。
5. 对象类型
JavaScript对象用大括号来书写,内容放置在大括号中,对象的属性通过名称和值(name: value)来定义,属性之间用逗号分隔。示例代码如下:
var person = {
firstName: "tom",
age: 23,
hairColor: "black"
};
上述代码中对象(person)有3个属性: firstName、age和hairColor。
5.2.3运算符
JavaScript运算符常用于执行算术运算、赋值、比较运算、逻辑运算。
1. 算术运算符
算术运算符用于变量或值之间的算术运算,如表5.2所示。
表5.2JavaScript算术运算符
运算符描述例子
+加x=y+1
-减x=y-1
*乘x=y*1
/除x=y/1
%求余数(保留整数)x=y%1
++累加x=++y
--递减x=--y
对于两个数字型的变量,变量之间使用“+”运算符表示相加; 当两个变量都为字符型,“+”运算符表示字符串的连接; 当一个变量为字符型,另一个变量为数值型,数值型会被解析为字符型进行字符串的连接。
2. 赋值运算符
对变量进行赋值使用赋值运算符,如表5.3所示。
表5.3JavaScript赋值运算符
运算符例子等同于
=x=y
+=x+=yx=x+y
-=x-=yx=x-y
*=x*=yx=x*y
/=x/=yx=x/y
%=x%=yx=x%y
3. 比较运算符
比较运算符表示变量之间的逻辑关系,如表5.4所示。
表5.4JavaScript比较运算符
运算符描述比较及结果
==等于5=6为false
===全等(值和类型)5===5为true,5===''5''为false
=!不等于5!=6为true
>大于5>6为false
<小于5<6为true
>=大于或等于5>==6为false
<=小于或等于5<==6为true
4. 逻辑运算符
逻辑运算符用于确定变量或值之间的逻辑关系,假设x=5 and y=2,逻辑运算符的使用如表5.5所示。
表5.5JavaScript逻辑运算符
运算符描述例子
&&和(x < 10 && y > 1)为true
||或(x == 3 || y == 5)为false
!非!(x == y)为true
5.2.4逻辑控制语句
逻辑控制语句分为条件判断语句和循环语句。
1. 条件判断语句
条件判断语句基于分支的思想,面对不同的情况或条件执行相应的选择,通用于某些代码的判断和重复执行。
1) if语句
当小括号内的条件为true时,大括号内部的代码才会执行。语法如下:
if (条件) {
当条件为true时才执行该代码
}
示例代码:
if (data > 100) {
console.log(data)
}
上述代码中当变量data值大于100时,会在Console控制台输出这个值。
2) if…else语句
当条件为true时执行if之后的代码,当条件为false时执行else之后的代码。语法如下:
if (条件) {
当条件为 true 时执行该代码
} else {
当条件为false时执行该代码
}
示例代码:
if (data > 100) {
console.log("输入的数字大于100")
} else {
console.log("输入的数字小于或等于100")
}
上述代码中当变量data值大于100时,会在Console控制台输出“输入的数字大于100”,否则,会在Console控制台输出“输入的数字小于或等于100”。
3) if…else if…else语句
在多个代码块中选择满足条件的一个去执行,先判断if条件,如果条件不成立,返回false后判断else if条件,如果条件成立,返回true并执行该条else if后的代码,如果仍不成立,继续判断下一个else if的条件。如果直到else时都没有条件成立,则执行else中的代码。语法如下:
if (条件1) {
当条件1为true时执行该代码
} else if (条件2) {
当条件2为true时执行该代码
} else {
当条件1和条件2都为false时执行该代码
}
示例代码:
if (data < 60) {
console.log("输入的数字小于60")
} else if (data >=60 && data <=80) {
console.log("输入的数字在60~80中")
} else {
console.log("输入的数字大于80")
}
当变量data值小于60时,执行if之后的代码,会在Console控制台输出“输入的数字小于60”; 当变量data值为60~80时,执行else if之后的代码,输出“输入的数字在60~80中”; 当前面的条件都不满足时,执行else后面的语句,输出“输入的数字大于80”。
4) switch语句
在多个代码块中选择满足条件的一个去执行,判断表达式通常为变量,表达式的值会与case中的值做匹配,如果匹配正确,会执行该case之后的代码块,使用break可以阻止代码继续执行,当条件都不满足时执行default之后的代码。
示例代码:
switch (n) {
case 1:
console.log("今天是星期一")
break;
case 2:
console.log("今天是星期二")
break;
case 3:
console.log("今天是星期三")
break;
case 4:
console.log("今天是星期四")
break;
case 5:
console.log("今天是星期五")
break;
case 6:
console.log("今天是星期六")
break;
case 7:
console.log("今天是星期日")
break;
default:
console.log("输入有误请重新输入")
}
当判断条件符合其中某一条件时,在Console控制台输入对应的星期数,然后程序执行break语句跳出循环; 当条件不满足所有case时,会执行default之后的代码,输出“输入有误请重新输入”。
2. 循环语句
循环语句通过判断条件来控制循环的次数,如果需要重复执行相关的动作就需要使用循环语句,循环语句可以提高代码的精简性。
例如,需要输出一个数组的全部元素,不使用循环语句代码如下:
console.log(array[0]);
console.log(array[1]);
console.log(array[2]);
console.log(array[3]);
使用循环语句代码如下:
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
上述代码通过循环将数组array中的所有元素在Console控制台输出。
1) for循环
for循环是经常使用的循环语句,语法如下:
for (语句1; 语句2; 语句3)
{
被执行的代码
}
语句1: 在循环开始前执行初始化操作; 语句2: 循环的条件,当返回值为true时,执行循环体,当返回值为false时,跳出该循环; 语句3: 当语句2返回值为true时执行。
示例代码:
for (i = 1; i < 10; i++) {
console.log(i)
}
console.log(i)
上述代码会在Console控制台分别输出1到9。
2) for/in循环
for/in循环用于循环对象属性,当循环体中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。
示例代码:
var person = {
firstName: "tom",
age: 23,
hairColor: "black"
};
var string = "";
var x;
for (x in person) {
string += person[x];
}
输出结果为: tom 23 black。
3) while循环
当条件满足时执行代码块,在每次执行完后会进行条件判断,条件为真会再次执行,直到条件不为真时跳出循环。语法如下:
while (条件) {
执行其中的代码
}
示例代码:
var i = 1;
while (i < 10) {
console.log("这是代码执行的第" + i + "次");
i++
}
变量i从初始值1,到不满足循环条件i<10,共执行了9次循环,程序在Console控制台执行了9次语句的输出。
4) do…while循环
首先执行一次do里面的代码块,如果条件为真会重复执行,当条件为假时跳出循环。语法如下:
do {
执行其中的代码
}
while (条件);
示例代码:
var i = 1;
do {
console.log("这是代码执行的第" + i + "次");
}
i++;
while (i < 1);
首先执行do里面的代码,然后变量i变为2,不满足while里面的条件直接跳出循环。
5.2.5定义和调用函数
函数的定义使用的关键字是function,示例代码:
function functionName(parameters) {
执行的代码
}
在小程序中函数的定义如下:
functionName:function(e){
执行的代码
}
函数的调用是指使用事先定义好的函数,函数本身是一种对象,示例代码:
function myFunction(a, b) {
return a + b;
}
myFunction(1, 2);//myFunction(1, 2) 返回值为3
5.2.6小程序中this和that的使用
this是JavaScript语言的一个关键字,可以调用函数。当函数运行时,this可以在函数内部使用,当函数使用场合发生变化时,this的值也会发生变化。在小程序开发中,小程序提供的API接口经常会有success、fail等回调函数来处理后续逻辑。当需要获取当前页面对象来对视图层进行渲染时,this只会指向调用函数的对象,如果想要获取页面的初始数据,在回调函数里面就不能使用this.data来获取,同时也不能使用this.setData()函数来更新数据,而是通过语句var this=that将this指向的对象复制到that中才可以执行后续操作。
5.3JavaScript在小程序中常见的交互场景
JavaScript是小程序编程中的基础语言,从本书附带案例的代码来看,JavaScript代码大约占整个小程序项目一半的代码量。全局文件app.js和所有的页面的JS文件都是由JavaScript来编写的,JavaScript代码主要实现业务逻辑处理和用户交互两方面的作用。52节主要从语法的角度介绍了JavaScript的变量、数据类型、控制语句和函数定义与调用,本节将以JavaScript在小程序中常见的交互场景出发,以案例教学的方式带领读者更深层次地理解JavaScript在小程序编程中的使用。
5.3.1购物车场景
尽管张小龙在2018微信公开课上指出,“小程序不是专门为电商准备的”,但由于强社交属性和微信支付的便捷性,电商成为小程序的重要应用场景。
51电商小程序中经常要用到购物车,购物车是JavaScript在小程序交互场景中的经典应用。本例实现一个简单的购物车,购物车初始状态和用户加购商品之后的购物车状态如图5.1和图5.2所示。
视频讲解
pages/addCaricon/addCaricon.wxml文件代码如下:
1.显示图标小案例
{{totalNum}}
数量 {{num}}
+
加入购物车
图5.1购物车初始状态
图5.2加购之后的购物车
pages/addCaricon/addCaricon.js文件代码如下:
Page({
data: {
num: 1,//数量初始化为1
totalNum: 0,//加入购物车的商品数量初始化为0
hasCart: false,//初始化默认不加入购物车
},
//增加数量
addCount: function() {
var num = this.data.num;
num++;//数量增加1
this.setData({
num: num//更新数量
})
},
//加入购物车
addCart: function() {
const num = this.data.num;//获取数量
var total = this.data.totalNum;//获取总数
this.setData({
hasCart: true,//用于控制加入购物车时的显示图标
totalNum: num + total//累计数量
})
wx.showToast({
title: "加入购物车成功",//弹出消息提示框
duration: 3000,
})
},
})
pages/addCaricon/addCaricon.wxss文件代码如下:
/*页面盒子*/
.goods-box {
position: relative;
padding: 0 30rpx;
text-align: center;
}
/*购物车位置*/
.carts-icon {
position: absolute;
right: 600rpx;
top: 490rpx;
width: 70rpx;
height: 70rpx;
}
/*购物车图标*/
.carts-icon image {
width: 100%;
height: 100%;
}
/*显示加入购物车图标*/
.carts-num {
position: absolute; right: 36rpx; width: 40rpx;
height: 40rpx; color:white;
font-size: 26rpx;
line-height: 40rpx;
border-radius: 50%;
background: #e4393c;
}
/*加入购物车导航*/
.operation {
height: 80rpx; line-height: 80rpx;
color:white; border-radius: 50rpx;
background: #ff9600;
font-size: 30rpx;
}
/*操作文本*/
.operation text {
display: inline-block;
height: 80rpx;
}
/*加入购物车数量*/
.operation-num {
width: 160rpx;
}
/*加入购物车符号*/
.operation-add {
width: 80rpx;
margin-right: 50rpx;
}
【代码讲解】addCaricon.wxml文件中“+”和“加入购物车”两个按钮绑定了点击事件。在addcart.js文件中为“+”按钮定义了事件函数addCount(),用于实现当用户点击“+”按钮时商品数量加1。为“加入购物车”按钮定义的函数addToCart(),用于实现当用户点击“加入购物车”时,一次性向购物车添加num件商品。当用户有加购行为,即点击了“加入购物车”按钮时,hasCart被赋值为true,则在购物车图标的左上角会出现当前购物车商品数量。
5.3.2下拉菜单场景
JavaScript在Web开发中经常被用来实现动态效果,在微信小程序开发者中也存在类似的场景。下拉菜单是JavaScript在小程序中常见的交互场景之一,当用户单击一级菜单时,二级菜单被弹出,当再次单击一级菜单时,二级菜单又消失。
52本例设计常见的小程序下拉菜单,图5.3是二级菜单没有弹出的状态,图5.4是二级菜单弹出的状态。
视频讲解
pages/subMenu/subMenu.wxml文件代码如下:
2.下拉菜单场景小案例
排序
时间
价格
{{item}}
图5.3下拉菜单弹出之前
图5.4下拉菜单弹出之后
pages/subMenu/subMenu.js文件代码如下:
Page({
data: {
li: ['默认排序', '离我最近', '价格最低', '价格最高'],
shownavindex: 0//数据初始化
},
//下拉事件
listmenu: function(e) {
if (this.data.openif) {
this.setData({
openif: false,//当前菜单没有下拉
shownavindex: 0//控制图标样式
})
} else {
this.setData({
content: this.data.li,//获取数组数据
openif: true,//当前菜单下拉
shownavindex: e.currentTarget.dataset.nav//控制图标样式
})
}
}
})
pages/subMenu/subMenu.wxss文件代码如下:
/*页面溢出隐藏*/
.page {
overflow: hidden;
}
/*导航外部样式*/
.nav {
position: relative;
z-index: 1;
display: flex;
flex-direction: row;
background: white;
}
/*导航内部样式*/
.nav-item {
display: flex;
flex: 1;
text-align: center;
height: 90rpx;
align-items: center;
justify-content: center;
font-size: 30rpx;
border: 1px solid gray;
}
/*导航下拉图标*/
.icon {
border: 10rpx solid transparent;
border-top: 10rpx solid gray;
margin-left: 12rpx;
}
/*下拉内部样式*/
.list {
display: none;
width: 100%;
overflow-y: scroll;
padding: 0 0 0 20rpx;
line-height: 100rpx;
background: white;
}
/*下拉内容样式*/
.list view {
border-bottom: 1px solid gray;
font-size: 32rpx;
}
/*点击导航内容文字后的样式*/
.nav-item.active .content {
color: skyblue;
}
/*点击导航下拉图标后的样式*/
.nav-item.active .icon {
border-bottom: 10rpx solid skyblue;
border-top: 0;
}
/*下拉动画样式*/
.down {
display: block;
animation: slidown 0.5s ease-in both;
}
@keyframes slidown {
from {
transform: translateY(-100%);
}
to {
transform: translateY(0%);
}
}
/*收起动画样式*/
.up {
display: block;
animation: slidup 0.5s ease-in both;
}
@keyframes slidup {
from {
transform: translateY(0%);
}
to {
transform: translateY(-100%);
}
}
【代码讲解】本例是JavaScript和样式布局结合的案例,在subMenu.js文件中设置初始值shownavindex: 0,使得导航的字体初始值为黑色。当用户点击菜单的时候激活事件函数listmenu(),此时content被赋值使得下拉菜单被弹出,shownavindex从0到1的变化使得一级菜单和向下箭头的样式也发生变化。
5.3.3栏目切换场景
在文章管理或者商品管理小程序中,往往有分类或者栏目的切换,当点击某一栏(某一区域),显示区域的文章和商品被重置为被点击的栏目下的文章和商品。
53本例设计商品栏目的切换效果,右侧显示区域根据左侧栏目的选择来显示对应的内容,运行效果如图5.5和图5.6所示。
视频讲解
图5.5“手机数码”栏目
图5.6“家用电器”栏目
pages/switchTab/switchTab.wxml文件代码如下:
3.栏目切换场景小案例
{{item}}
{{item}}
pages/switchTab/switchTab.js文件代码如下:
Page({
data: {
currentTab: 0,//初始化数据
list1: ["手机数码", "家用电器", "运动户外", "优选水果", "食品生鲜", "运动户外", "电脑办公", "体育用品", "美妆护肤"],
list2: ["切换到手机数码", "切换到家用电器", "切换到运动户外", "切换到优选水果", "切换到食品生鲜", "切换到运动户外", "切换到电脑办公", "切换到体育用品", "切换到美妆护肤"],
},
switchTab: function(e) {
var that = this;
var id = e.target.id;//获取id
if (this.data.currentTab == id) {
return//与currentTab值一致返回
} else {
that.setData({
currentTab: id//设置currentTab值为id
});
}
}
})
pages/switchTab/switchTab.wxss文件代码如下:
/*布局样式*/
.content {
display: flex;
flex-direction: row;
}
/*左边样式*/
.left {
width: 25%;
font-size: 30rpx;
}
scroll-view {
height: 90%;
}
/*左边元素样式*/
.left view {
text-align: center;
height: 100rpx;
line-height: 100rpx;
}
/*右边样式*/
.right {
width: 75%;
}
【代码讲解】本例switchTab.wxml使用flex布局实现栏目和内容的左右分布,左侧是组件,右侧是组件,当用户点击左侧栏目的时候switchTab.js获取栏目的id,并把id赋值给current,此时右侧的组件的第id项被显示,从而实现了左右的同步。本例巧妙地使用了组件的current属性实现内容的切换。
5.3.4系统设置场景
大部分的App和小程序都有系统设置功能,系统设置功能主要是用户输入或者选中数据,JavaScript获取用户设置的数据来修改
视频讲解
系统配置参数。系统设计场景是JavaScript在微信小程序中常见的应用场景。
54本例以辩论赛小程序为背景,系统设置功能可以对立论、驳立论、质辩、自由辩论和总结陈词等环节的辩论时间和倒计时时间进行设置,系统设置页效果如图5.7所示,项目首页简单设计如图5.8所示。
图5.7设置页面
图5.8项目首页
app.js文件代码如下:
App({
data: { configs: [{ name: "立论阶段", time: 180, voice: 15 }, { name: "驳立论阶段", time: 180, voice: 15 }, { name: "质辩环节", time: 180, voice: 15 }, { name: "自由辩论", time: 180, voice: 15 }, { name: "总结陈词", time: 180, voice: 15 }]},
onLaunch: function() {
wx.setStorageSync('configs',this.data.configs);
}
})
pages/setting/setting.wxml文件代码如下:
立论阶段
时间限制(秒)
声音提醒
驳立论阶段
时间限制(秒)
声音提醒
质辩环节
时间限制(秒)
声音提醒
自由辩论
时间限制(秒)
声音提醒
总结陈词
时间限制(秒)
声音提醒
pages/setting/setting.js文件代码如下:
Page({
data:{
configs:[]
},
onLoad:function(options){
var configs = wx.getStorageSync('configs');
this.setData({configs:configs});
},
sliderChange:function(e){
var id = e.target.id;
this.data.configs[id].time = e.detail.value
wx.setStorageSync('configs', this.data.configs);
console.log(this.data.configs)
},
radioChange:function(e){
var id = e.target.id;
this.data.configs[id].voice = e.detail.value
wx.setStorageSync('configs', this.data.configs);
console.log(this.data.configs)
}
})
pages/setting/setting.wxss文件代码如下:
/*页面样式*/
page {
background-color: skyblue; color: black;
}
/*标题样式*/
.title {
font-size: 40rpx; height: 72rpx;
line-height: 72rpx; padding-left: 20rpx;
}
/*分隔线样式*/
.hr {
margin: 12px; width: 100%;
height: 1px; background-color: grey;
}
/*文字样式*/
text {
padding-left: 20rpx; font-size: 30rpx;
}
/*选项样式*/
.item {
margin: 12rpx;
}
/*标签样式*/
.item label {
margin: 10px;
}
pages/index/index.wxml文件代码如下:
{{item.name}}设置的参数如下: 时间限制是{{item.time}},倒计时时间是{{item.voice}}秒
pages/index/index.js文件代码如下:
Page({
data: {
configs: []
},
onShow: function (options) {
var configs = wx.getStorageSync('configs');
this.setData({ configs: configs });
},
})
pages/index/index.wxss文件代码如下:
.setitem{
height: 30rpx;
}
view {
padding-left: 10rpx;
}
【代码讲解】本例中辩论赛数据configs存放在app.js文件中,通过wx.setStorageSync()和wx.getStorageSync()接口实现多个页面之间数据的共享和维护,setting页面的和组件输入的数据被事件函数sliderChange()和radioChange()用来修改全局数据configs。项目需注意修改全局数据configs时的下标问题。
视频讲解
5.4实训项目——计算器小案例
本实训项目设计一个计算器,实现了加、减、乘、除运算。程序运行效果如图5.6所示。本项目没有涉及小程序复杂的接口,使用的是第4章样式与布局和第5章JavaScript基础的知识点。项目的设计思路是先编写WXML文件,然后
编写JS接收WXML的数据的代码,再编写加、减、乘、除运算的逻辑代码,最后编写WXSS文件。程序执行效果如图5.9所示。
图5.9计算器示例图
pages/calculator/addList.wxml文件代码如下:
{{screenData}}
back
C
+/-
÷
7
8
9
×
4
5
6
-
1
2
3
+
0
.
=
pages/calculator/addList.js文件代码如下:
Page({
data: {
id1: "back",
id2: "clear",
id3: "negative",
id4: "÷",
id5: "7",
id6: "8",
id7: "9",
id8: "×",
id9: "4",
id10: "5",
id11: "6",
id12: "-",
id13: "1",
id14: "2",
id15: "3",
id16: "+",
id17: "0",
id18: ".",
id19: "=",
screenData: "0",//屏幕数字初始化
lastInput: false,//控制输入
array: [],//定义一个空数组
},
onclickButton: function(e) {
var id = e.target.id;
if (id == this.data.id1) {//退格
var data = this.data.screenData;
if (data == 0) {
return;
}
data = data.substring(0, data.length - 1);//删除最后一位
if (data == "" || data == "-") {//如果为空或者符号置零
data = 0;
}
this.setData({
screenData: data
});
this.data.array.pop();
this.data.array.push(data);
} else if (id == this.data.id2) {//清屏
this.setData({
screenData: "0"
});
this.data.array.length = 0;
} else if (id == this.data.id3) {//正负号
var data = this.data.screenData;
if (data == 0) {
return;
}
var firstWord = data.substring(0, 1);
if (firstWord == "-") {
data = data.substring(1, data.length);//去掉负号
this.data.array.shift();
} else {
data = "-" + data;
this.data.array.unshift("-");//增加负号
}
this.setData({
screenData: data
});
} else if (id == this.data.id19) {//=
var data = this.data.screenData;
if (data == 0) {
return;
}
var lastWord = data.substring(data.length - 1, data.length);
if (isNaN(lastWord)) {
return;//最后一位不是数字返回
}
var num = "";//定义一个字符串
var lastInput;
var array = this.data.array;
var optaration = [];
for (var i in array) {
if (isNaN(array[i]) == false || array[i] == this.data.id18 || array[i]
== this.data.id3) {
num += array[i];//对小数点或者正负号进行合并处理
} else {//加减乘除单独处理
lastInput = array[i];
optaration.push(num);
optaration.push(array[i]);
num = "";
}
}
optaration.push(Number(num));
var result = Number(optaration[0]) * 1.0;
for (var i = 1; i < optaration.length; i++) {
if (isNaN(optaration[i])) {
if (optaration[1] == this.data.id4) {//除运算
result /= Number(optaration[i + 1]);
} else if (optaration[1] == this.data.id8) {//乘运算
result *= Number(optaration[i + 1]);
} else if (optaration[1] == this.data.id12) {//减运算
result -= Number(optaration[i + 1]);
} else if (optaration[1] == this.data.id16) {//加运算
result += Number(optaration[i + 1]);
}
}
}
this.data.array.length = 0;
this.data.array.push(result);
this.setData({
screenData: result + ""//将计算结果赋值用于在屏幕上显示
});
} else {
if (id == this.data.id4 || id == this.data.id8 || id == this.data.id12 || id == this.data.id16) {
if (this.data.lastInput == true || this.data.screenData == 0) {
return;//开始不允许输入加减乘除
}
}
var vd = this.data.screenData;
var data;
if (vd == 0) {
data = id;
} else {
data = vd + id;//用于连续输入数字
}
this.setData({
screenData: data
});
this.data.array.push(id);
if (id == this.data.id4 || id == this.data.id8 || id == this.data.id12 || id == this.data.id16) {
this.setData({
lastInput: true
});
} else {
this.setData({
lastInput: false
});
}
}
}
})
pages/calculator/addList.wxss文件代码如下:
/*外部布局*/
.demo-box {
background-color: black; padding: 10rpx;
}
/*输入框样式 */
.input-screen {
background-color: white; border-radius: 20rpx; text-align: right;
width: 710rpx; height: 120rpx; line-height: 120rpx;
padding-right: 20rpx; margin-bottom: 40rpx;
}
/*按钮布局方式*/
.btn-group {
display: flex; flex-direction: row;
}
/*按钮样式*/
.item {
width: 150rpx; height: 150rpx;
margin: 15rpx; border-radius: 100rpx;
text-align: center; line-height: 150rpx;
}
/*按钮0样式*/
.item1 {
width: 320rpx; height: 150rpx;
margin: 10rpx; border-radius: 100rpx;
text-align: center; line-height: 150rpx;
}
/*颜色样式*/
.green {
color: #f7f7f7; background: #7ccd7c;
}
/*颜色样式*/
.blue {
color: #f7f7f7; background: #0095cd;
}
【代码讲解】本项目在addList.wxml文件和addList.wxss文件中完成页面的布局,为每个按钮绑定点击事件; 在JS文件中首先设置允许连续输入操作数并且不允许连续输入操作符,然后分别为每个按钮设置交互功能,包括退格、清零和正负号,接着定义等号的交互,数字在连续输入时将中间结果保存在数组中,最后实现加减乘除运算。由于考虑到篇幅问题,设计功能完整的计算器代码较多,故没有涉及运算的优先级处理,有兴趣的读者可以自行修改本项目。