第3章豆豆云助教“我的”页面模块开发

从此我不再仰脸看青天,不再低头看白水,只谨慎着我双双的脚步,我要一步
一步踏在泥土上,打上深深的脚印。

——朱自清

不积跬步,无以至千里; 不积小流,无以成江海。

曾经有一个少年,向一位大师求教如何才能做到跋山涉水不费吹灰之力,大师没有直接传授给他技艺,
只叫他每天为自己养猪,并且有一个要求,必须抱着猪越过一座座山坡,翻过一条条河沟,晚上再抱回家,中途不能放下猪。日子一天天过去,少年心中不满,心想大师怎么每天只让自己为他养猪,但碍于情面也就没有吱声。两年后的某一天,大师突然对他说: “今天你不必抱着猪,自己上山去吧。”少年满心疑惑,但也照做了。意外的是,一路上他只觉得身轻如燕,脚步飞快,不一会儿便到了山顶。
少年恍然大悟,在过去的两年里,小猪仔一天天长大,从几斤长到了两百多斤,而自己每天抱着猪上山已经练就了一身的爬山好本领。
学习也是如此,点滴积累会让我们在不知不觉中变成高手,小程序开发的学习正式开始了,望同学们持之以恒,同时也要对自己充满信心。本章主要通过“我的”页面模块开发正式开始豆豆云助教的开发。完成“我的”页面模块开发之前,需要先完成授权登录页面和注册页面,拥有授权信息与注册信息后,才能在“我的”页面将个人信息显示出来。
3.1授权登录页面
本节主要分为两部分,首先讲解授权登录页面涉及的知识点,然后在理解的情况下完成授权登录页面的开发。



3.1.1授权页面知识点讲解
1. 小程序登录







小程序可以通过微信官方提供的登录功能方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。如图31所示,小程序通过wx.login()获取code(登录凭证),然后通过wx.request()发送code至开发者服务器,开发者服务器将登录凭证
AppID、appsecret与code用于校验微信接口,微信接口服务向开发者服务器返回用户唯一标识
openid和会话密钥 session_key。开发者服务器实现自定义登录状态与openid、session_key的关联,并向小程序返回自定义状态。小程序将自定义登录状态存入storage,并用于后续wx.request发起业务请求。



图31小程序登录流程时序


对于某个微信小程序,每个用户访问该小程序都会产生一个唯一的openid,这个openid为用户访问该小程序的标识符,即每个用户的openid都是不一样的。因此,可以把openid作为用户唯一标识符(类似身份证号),并存于数据库中用于后续操作。

开发者服务器与微信接口服务之间的交互是由后台实现的,本节主要以小程序前端与开发者服务器之间的交互为主,后台部分会在第9章中详细介绍。

2. wx.login()

调用wx.login()接口获取code,通过code进而换取用户登录状态信息,其中wx.login()接口属性如表31所示。



表31wx.login()接口属性





属性类型必填说明

timeoutnumber否超时时间,单位为ms
successfunction否接口调用成功的回调函数
failfunction否接口调用失败的回调函数
completefunction否接口调用结束的回调函数(无论调用成功还是失败都会执行)

由于app.js会先于其他页面执行,所以比较适合处理一些注册函数,因此将wx.login()方法写在app.js文件中。
3. wx.request()
wx.request()主要用于发送HTTPS网络请求,其属性详见表32。



表32wx.request属性





属性类型默认值必填说明

urlstring是开发者服务器接口地址
datastring/object/
ArrayBuffer否请求参数
headerobject否设置请求的 header,header 中不能设置 Referer。contenttype 默认为 application/json
methodstringGET否HTTP请求方法
dataTypestringjson否返回的数据格式
responseTypestringtext否响应的数据类型
successfunction否接口调用成功的回调函数
failfunction否接口调用失败的回调函数
completefunction否接口调用结束的回调函数(无论调用成功还是失败都会执行)

这里以小程序登录中小程序向开发者服务器发送wx.request请求为例,调用微信官方的wx.login()接口会返回一串jscode,服务器使用jscode、AppID、appsecret三个参数向微信请求得到openid,这一步后台已经封装完成,并提供一个开放接口: 

https://zjgsujiaoxue.applinzi.com/index.php/Api/Weixin/code_to_openidv2

具体代码如下: 

//登录

wx.login({

success: res => {

//发送 res.code 到后台换取 openid, session_key, unionid

wx.request({

url:'https://zjgsujiaoxue.applinzi.com/index.php/Api/Weixin/code_to_openidv2',

data: {

'code': res.code,

'from': 'wxbf9778a9934310a1'

},

success:function (res) {

console.log(res.data)

//将sessionid保存到本地storage

wx.setStorageSync('jiaoxue_OPENID', res.data.openid)

},

fail:function (res) {

console.log('res' + res)

}

})

}

})

上述代码中,通过wx.login()方法,成功返回res,其中res.code为微信官方返回的code,通过wx.request
()发起请求,请求参数为code与appid,当请求成功时,后台会返回一个数组,数组中包含的值是由后台代码决定的,其中就包含了openid,这里可以使用console.log(res.data)来看一下返回的数组中所包含的值,如图32所示。



图32wx.request()请求的返回值


4. 数据缓存

每个微信小程序都可以有自己的本地缓存,通过数据缓存API可以对本地缓存进行设置、获取和清理。同一个微信用户,同一个小程序storage上限为 10MB。localStorage 以用户维度隔离,同一台设备上,A用户无法读取到B用户的数据。
注意:  如果用户存储空间不足,微信会清空最近且最久未使用的小程序的本地缓存。因此不建议将关键信息全部存在localStorage,以防储存空间不足或用户换设备的情况。
数据缓存API主要有五类,包括数据的存储、获取、移除、清空以及获取存储信息,每类均包含同步与异步两种,具体详见表33。



表33数据缓存API函数类型





函数名说明

wx.setStorage(Object object)数据的存储(异步)
wx.setStorageSync(string key, any data)数据的存储(同步)
wx.getStorage(Object object)数据的获取(异步)
wx.getStorageSync(string key)数据的获取(同步)
wx.getStorageInfo(Object object)存储信息的获取(异步)
wx.getStorageInfoSync()存储信息的获取(同步)
wx.removeStorage(Object object)数据的移除(异步)
wx.removeStorageSync(string key)数据的移除(同步)
wx.clearStorage(Object object)数据的清空(异步)
wx.clearStorageSync()数据的清空(同步)

其中,Sync为英文单词synchronization的前四个字母,表示同步,因此API函数中带有Sync后缀的函数为同步函数。同步函数与异步函数之间的区别是,异步函数不会阻塞当前任务,同步函数缓存直到同步方法处理完才能继续往下执行。另外异步函数中含有成功回调函数,可用于数据处理成功后的操作。

这里以wx.login()中使用的wx.setStroageSync()为例,将wx.request()返回的openid存储于本地,方便openid的获取。使用wx.setStorageSync()的代码示例如下: 

wx.setStorageSync('jiaoxue_OPENID', res.data.openid)

编译后,可以在调试器的Storage面板中看到openid已存入本地,Key的值为jiaoxue_OPENID,Value的值为用户的openid,如图33所示。



图33Storage面板中的本地缓存


如果使用wx.setStorage()进行数据存储,可以对数据存储成功后再进行操作,代码较wx.setStorageSync()有变化,具体代码如下: 

wx.setStorage({

key:'jiaoxue_OPENID',

data:res.data.openid,

success:function(){

console.log('存储成功')

}

})

编译后,同样将openid存储于本地缓存,并执行成功回调函数,Console面板打印出“存储成功”,如图34所示。



图34Console面板中的“存储成功”



需要使用本地缓存中的openid时,可以用wx.getStorageSync('jiaoxue_OPENID')从本地获取openid,并赋值给相应的变量。当然wx.getStorage()也可以,这里不赘述。
5. wx.showModal()
小程序使用wx.showModal(Object object)显示模态对话框,其中object参数说明如表34所示。



表34wx.showModal()中Object参数说明





属性类型默认值必填说明

titlestring是提示的标题
contentstring是提示的内容
showCancelbooleantrue否是否显示取消按钮
cancelTextstring'取消'否取消按钮的文字,最多4个字符
cancelColorstring#000000否取消按钮的文字颜色,必须是十六进制格式的颜色字符串
confirmTextstring'确定'否确认按钮的文字,最多4个字符
confirmColorstring#576B95否确认按钮的文字颜色,必须是十六进制格式的颜色字符串
successfunction否接口调用成功的回调函数
failfunction否接口调用失败的回调函数
completefunction否接口调用结束的回调函数(无论调用成功还是失败都会执行)

其中success()回调函数的返回参数详见表35。



表35success()回调函数的返回参数





属性类型说明最低版本

confirmboolean为 true 时,表示用户单击了“确定”按钮
cancelboolean为 true 时,表示用户单击了“取消”按钮(用于 Android 系统区分单击“蒙层”关闭还是
单击“取消”按钮关闭)1.0.0

在进入豆豆云助教时,如果用户没有注册过,会弹出模态对话框提示用户前往注册,具体代码如下: 

if (!res.data.is_register) {

wx.showModal({

title:'提示',

content:'请先注册',

showCancel:false,

confirmText:"确定",

success:function(res) {

wx.navigateTo({

url:'/pages/register/userlogin',

})

}

})

}

编译后,弹出模态对话框,提示用户前往注册,如图35和图36所示。



图35模态对话框提示用户注册(不含“取消”按钮)





图36模态对话框提示用户注册(含“取消”按钮)


另外尝试在该wx.showModel()的基础上,进行简单的修改,首先将showCancel属性删除,这样模态
对话框会默认showCancel的值为true。然后添加一个成功回调函数success(),通过console.log()查看success()的返回值具体有哪些,具体代码如下。

wx.showModal({

title:'提示',

content:'请先注册',

confirmText:"确定",

success:function(res) {

console.log(res)

if(res.confirm){

console.log('"确定"按钮被单击')

wx.navigateTo({

url:'/pages/register/userlogin',

})

}else if(res.cancel){

console.log('"取消"按钮被单击')

}

}

})

编译后,效果如图36所示。在Console面板中可以看到打印出来的success()函数的返回值,如图37所示。



图37success()函数的返回值



3.1.2授权登录页面实现
1. 新建小程序项目







首先新建一个小程序项目,具体操作与1.1.3节中Hello World小程序的新建一样,新建项目时,建议开发者自定义项目名称,并且在存放小程序项目的目录下新建一个空的文件夹,项目目录选择该文件夹,这样方便以后寻找项目所在目录。项目名称可自定义,本书将项目名称命名为doudouyun,与项目相关,具体如图38所示。
2. 新建userlogin页面

完成项目新建后,需要新建一个授权登录页面,首先右击pages目录,
在弹出的快捷菜单中选择“新建目录”命令,新建目录并命名为register。然后右击register目录,
在弹出的快捷菜单中选择“新建Page”命令,
新建Page并命名为userlogin,如图39和图310所示。



图38新建doudouyun(豆豆云)项目





图39选择“新建目录”命令





图310选择“新建Page”命令


选择“新建Page”命令而不选择一个一个文件新建,原因是选择“新建Page”命令时,app.json的pages属性中会自动添加新建的页面,开发者不需要再手动添加页面路径了。
3. userlogin页面开发

userlogin页面的功能主要是授权,与Hello World小程序中index页面的功能相似,因此只要在Hello World小程序的基础上进行简单修改即可。

首先是wxml文件。userlogin页面结构主要由view、text与button三种标签组成,并使用class属性定义对应标签的样式,页面中主要有一个“单击授权登录”按钮,具体代码如下: 

<!--userlogin.wxml-->

<view class="container">

<view class="usermotto">

<text class="user-motto">微信授权</text>

</view>

<view class="userinfo">

<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo=
"getUserInfo">单击授权登录</button>

</view>

</view>

然后是wxss文件。相比于Hello World小程序中的index.wxss文件,少了两种样式类型,主要保留了userinfo与usermotto,具体代码如下: 

/**userlogin.wxss**/

.userinfo {

display: flex;

flex-direction: column;

align-items: center;

}

.usermotto {

margin-top: 150px;

text-align: center;

}

为了获得更好的用户体验,一些细节也要注意一下,比如当用户进入授权登录页面时,页面导航栏的标题文字也相应变为“授权页面”,主要就是在json文件中加上一行代码,具体代码如下: 

{

"navigationBarTitleText": "授权页面"

}


最后就是userlogin.js中的相关逻辑代码。userlogin页面的逻辑与Hello World小程序中index页面的逻辑基本一样,只是简单调整了一下,原有的事件处理函数bindViewTap()在授权页面不需要了,直接删除即可。在onLoad()函数最后加上一个判断语句,判断当hasUserInfo!=false时,跳转至register页面,即注册页面,具体代码如下: 

if (this.data.hasUserInfo) {

wx.navigateTo({

url:'./register',

})

}

另外getUserInfo()函数中也相应加上一个页面跳转函数wx.navigateTo(),实现当触发事件处理函数getUserInfo
()时,跳转至register页面,具体代码如下: 

getUserInfo:function (e) {

wx.navigateTo({

url:'./register',

})

app.globalData.userInfo = e.detail.userInfo

this.setData({

userInfo: e.detail.userInfo,

hasUserInfo:true

})

}

最后授权登录页面的效果如图311所示。



图311授权登录页面效果


如果之前已经授权过了,看不到想要的授权页面,可以单击工具栏中间区域的“清缓存”按钮清除授权记录。
4. app.js

除了完成userlogin页面的开发,还需要对app.js文件进行修改。首先是wx.login()方法需要完善,
这样才能实现小程序的登录功能,最终代码如下: 

wx.login({

success: res => {

//发送 res.code 到后台换取 openid, session_key, unionid

wx.request({

url:'https://zjgsujiaoxue.applinzi.com/index.php/Api/Weixin/code_to_openidv2',

data: {

'code': res.code,

'from': 'wx5ee2da791099a208'

},

success:function (res) {

console.log(res.data)

//将sessionid保存到本地storage

wx.setStorageSync('jiaoxue_OPENID', res.data.openid)

if (!res.data.is_register) {

wx.showModal({

title:'提示',

content:'请先注册',

showCancel:false,

confirmText:"确定",

success:function (res) {

wx.navigateTo({

url:'/pages/register/userlogin',

})

}

})

}

},

fail:function (res) {

console.log('res' + res)

}

})

}

})

注意,wx.request()的data数组中,from对应的是开发者的appid,因此appid的值需要改成开发者自己的appid。
编译后,发现Console面板会提示错误,如图312所示。



图312提示request中url不在合法域名列表


解决方法: 单击工具栏右侧区域的“详情”按钮,勾选“不校验合法域名”
复选框即可,如图313所示。




图313勾选“不校验合法域名”复选框



勾选“不校验合法域名”复选框后,重新编译一次,发现Console面板提示“该appid未注册”,如图314所示。



图314提示“该appid未注册”



这是为了让所有开发者在学习豆豆云前端开发时,使用提供给所有开发者的云后台。豆豆云
为开发者专门提供了一个接口,前往注册一下,即可使用提供的云后台。因此要使wx.login方法的wx.request()中的url实现访问后台,需要前往https://zjgsujiaoxue.applinzi.com/index.php/Page/Index/register
进行注册。调用该接口需要两个参数,即开发者的appid与appsecret,如图315所示。



图315API接口注册



填写appid与appsecret后,单击Submit按钮即可完成API接口注册。API接口注册完成后,重新编译代码即可看到Console面板中wx.request()的返回值,主要包括is_login、is_register和openid,如图316所示。



图316wx.request()返回值


到这里,用户第一次进入授权登录页面的跳转逻辑已经完成。
3.2注册页面
如果要在userlogin的逻辑中跳转到注册页面,就需要新建一个register页面。本节主要先对注册页面中的一些知识点进行讲解,然后再具体介绍如何完成注册页面的开发。
3.2.1注册页面知识点讲解






注册页面主要新增了三个知识点,分别是微信官方UI库WeUI、bindchange事件和openAlert()函数。

1. 微信官方UI库WeUI

WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。它包含button、cell、dialog、progress、toast、article、actionsheet、icon等各种元素。WeUI基础样式库下载地址为https://github.com/Tencent/weuiwxss。开发者可以将样式库下载并使用微信Web开发者工具打开dist目录(请注意,是dist目录,不是整个项目),导入dist目录后,可以预览样式库,如图317所示。
开发者可以在样式库里选择自己所需要的样式,然后直接将需要的样式对应的wxml代码复制、粘贴至自己的项目中,然后将WeUI中style文件复制至自己的项目目录中,如将图318目录下style文件夹复制至图319目录下。
将style文件夹复制至自己开发的项目后,还需要在app.wxss文件中使用@import导入
WeUI的样式,如图320所示。到这里,即可正常使用WeUI库中微信的官方样式。




图317预览WeUI样式库





图318dist目录下的style文件夹





图319doudouyun项目下的style文件夹





图320导入WeUI样式


2. bindchange事件
bindchange事件与bindtap事件不同,它主要是当输入框中的内容发生改变时,触发对应的事件处理函数,并且输入框中的值可以通过event.detail.value来获取。举个简单的例子,代码如下。
wxml文件代码: 

<view class="weui-cells weui-cells_after-title">

<view class="weui-cell weui-cell_input">

<view class="weui-cell__hd">

<view class="weui-label">qq</view>

</view>

<view class="weui-cell__bd">

<input class="weui-input" placeholder="请输入qq" bindchange="changevalue"/>

</view>

</view>

</view>

js文件代码: 

Page({

data: {

qq:0

},

changevalue:function(event){

console.log(event)

this.setData({

qq: event.detail.value

})

},

})

页面效果如图321所示。



图321bindchange使用样例


当在输入框中输入内容后,单击其他空白处,可以打印出changevalue()函数的返回值,会发现输入的内容被存放在detail的value中,如图322所示。



图322bindchange事件触发后value的值


3. openAlert()函数
openAlert()函数是在js文件中自定义的一个函数,在定义函数后,可以在其他函数中使用this.openAlert()调用openAlert()函数。












3.2.2注册页面实现
注册页面实现主要分为两部分: 一部分是注册页面的页面布局; 另一部分则是注册页面的功能实现。
1.  注册页面的页面布局
与新建userlogin页面一样,在register目录下,右击register,
在弹出的快捷菜单中选择“新建Page”命令新建Page并命名为register。建完register页面后,接下来就是往页面里写东西了。

首先看register页面最后的界面需要做成什么样,如图323所示。
然后在WeUI基础样式库中找到对应的样式,其中姓名、手机号、学校、学号和入学年份是一个输入框,对应的是WeUI中表单
下Input里面的一种样式,如图324所示。单击模拟器下方的“打开”按钮,即可在编辑器的目录结构区找到该页面对应的目录,打开input.wxml文件,找到该样式对应的代码,如图325所示。将其复制至doudouyun项目的register.wxml中,其中这段代码最后还少了一个</view>,作为最开始<view>的结束标签。



图323注册页面效果





图324WeUI样式库中对应的Input样式





图325input.wxml中样式对应的代码


以姓名的input为例,其他项都与姓名的操作一致,
register.wxml代码如下: 

<view class="weui-cells weui-cells_after-title">

<view class="weui-cell weui-cell_input">

<view class="weui-cell__hd">

<view class="weui-label">姓名</view>

</view>

<view class="weui-cell__bd">

<input class="weui-input" placeholder="请输入姓名" bindchange="changeName"/>

</view>

</view>

</view>

2. 注册页面的功能实现
注册页面的功能实现需要完善register.js中的代码,代码如下:  

Page({

data: {

name:''

},

changeName:function(e){

this.setData({

name: e.detail.value

})

}

})

其他注册信息的输入框与姓名一样,分别加入wxml代码,并在data数组中加入对应的变量,将对应的bindchange()函数进行修改即可。
除了输入框外,最后还有一个“提交”按钮,在WeUI样式库中的表单下的button中找到对应的button样式,如图326所示。




图326WeUI样式库中对应的button样式


然后在register.wxml文件的最后加上一段button的代码,具体代码如下: 

<view class="page__bd page__bd_spacing submit">

<button class="weui-btn" type="primary">提交</button>

</view>

其中,第一个<view>的class类的最后新加一个submit子类,并在wxss文件中写submit子类样式的相关属性,主要是为了调整“提交”按钮的样式。
如果margin后面只有两个参数,第一个表示top和bottom,第二个表示left和right。“margin: 0 auto”表示上下边界为0,左右则根据宽度自适应相同值(即居中); paddingtop的作用是使button与input之间有一定距离,而不是紧紧连接在一起。设置width为屏幕宽度的90%。具体代码如下: 

.submit{

margin: 0 auto;

padding-top: 15px;

width: 90%;

}

“提交”按钮绑定的事件处理函数bindSubmit(),主要是向后台发送用户注册信息,这为后台提供了一个API接口用于将注册信息存入后台数据库。请求成功后,跳转至index页面,具体代码如下: 

bindSubmit:function (e) {

wx.request({

url:'http://zjgsujiaoxue.applinzi.com/index.php/Api/User/register_by_openid',

data: {

openid: wx.getStorageSync('jiaoxue_OPENID'),

globalData:JSON.stringify(app.globalData.userInfo),

name:this.data.name,

tel:this.data.tel,

school:this.data.school,

num:this.data.num,

enter_year:this.data.year

},

success: res => {

if (res.data.is_register) {

wx.redirectTo({

url:'../index/index',

})

}

},

fail: res => {

},

})

},

3.3“我的”页面

用户在注册页面填入注册信息后,单击“提交”按钮,完成豆豆云的注册。然后跳转至index页面,这里需要新建一个
“我的”页面,用于用户查看注册信息,本节主要讲解如何开发“我的”页面。
3.3.1“我的”页面知识点讲解

“我的”页面主要新增了两个知识点: 微信小程序媒体组件image的属性和wxss属性。
1. image属性
image组件的属性详见表36。



表36image组件的属性





属性名类型说明


srcstring图片资源地址
modestring图片裁剪、缩放的模式
binderrorHandleEvent当错误发生时,发布到AppService的事件名,事件对象event.detail = { errMsg: 'something wrong' }

bindloadHandleEvent当图片载入完毕时,发布到AppService的事件名,事件对象event.detail = {height:'图片高度px', width:'图片宽度px'}

注: image组件默认宽度为300px、高度为225px。

图327中image组件用到了三目运算作为判断。三目运算符定义为: <表达式1> ?<表达式2> : <表达式3>
。其含义是: 先求表达式1的值,如果为真,则执行表达式2,并返回表达式2的结果; 如果表达式1的值为假,则执行表达式3,并返回表达式3的结果。



图327images组件



试验中的image链接语句src="{{userInfo.head_img1?userInfo.head_img:'/images/default_head_circle.png'}} 是三目运算符。首先判断Storage当中是否获取到userInfo.head_img,如图328所示。



图328userinfo中头像信息



如果Storage中获取到userInfo.head_img,则图片资源地址为userInfo.head_img,反之则为image文件中的default_head_circle.png图片。
2. wxss属性
rpx(responsive pixel):  可以根据屏幕宽度进行自适应调节。规定屏幕宽为750rpx。如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。设备对应的单位换算详见表37。



表37设备对应的单位换算





设备rpx换算px(屏幕宽度/750)px换算rpx(750/屏幕宽度)

iPhone51rpx=0.42px1px=2.34rpx
iPhone61rpx=0.5px1px=2rpx
iPhone6 Plus1rpx=0.552px1px=1.81rpx


建议: 开发微信小程序时设计师可以用iPhone6作为视觉稿的标准。
注意:  在较小的屏幕上不可避免地会有一些毛刺,请在开发时尽量避免这种情况。


.head_img {

height: 120rpx;

width: 120rpx;

border-radius: 50%;

}

.weui-cell__ft {

color: #000;

}

上述代码中height为图片的高度,width为图片的宽度,borderradius为圆角的角度,为图片添加圆角边框,例如borderradius: 50%,就是以百分比定义圆角的形状。












3.3.2“我的”页面实现
右击pages,
在弹出的快捷菜单中选择“新建目录”命令,
新建目录并命名为my。右击my目录,
在弹出的快捷菜单中选择“新建Page”命令,
新建Page并命名为myinfo。
“我的”页面的实现与注册页面基本相同。其中“我的”页面的效果如图329所示。
首先就是在WeUI样式库中找到对应的样式,查看WeUI中list样式,发现要找的是“带说明带跳转的列表项”,如
图330所示。myinfo.wxml文件中的代码如下: 




图329“我的”页面效果




图330WeUI样式库中对应的list样式



<view class="weui-cells weui-cells_after-title">

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">头像</view>

<view class="weui-cell__ft weui-cell__ft_in-access">

<image class= "head_img" src="{{userinfo.head_img?userinfo.head_img:'/images/default_head_circle.png'}}">

</image>

</view>

</navigator>

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">姓名</view>

<view class="weui-cell__ft weui-cell__ft_in-access">{{userinfo.name}}</view>

</navigator>

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">手机号</view>

<view class="weui-cell__ft weui-cell__ft_in-access">{{userinfo.tel}}</view>

</navigator>

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">性别</view>

<view class="weui-cell__ft weui-cell__ft_in-access">{{userinfo.sex}}</view>

</navigator>

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">学校</view>

<view class="weui-cell__ft weui-cell__ft_in-access">{{userinfo.school}}</view>

</navigator>

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">学号</view>

<view class="weui-cell__ft weui-cell__ft_in-access">{{userinfo.number}}</view>

</navigator>

<navigator url="" class="weui-cell weui-cell_access" hover-class="weui-cell_active">

<view class="weui-cell__bd">入学年份</view>

<view class="weui-cell__ft weui-cell__ft_in-access">{{userinfo.enter_year}}
</view>

</navigator>

</view>

其中,userinfo的值是通过向后台访问请求,获取到的用户信息,并保存在本地,然后从本地读取出来进行赋值。该请求的代码写在app.js中,具体代码如下: 

wx.request({

url:'https://zjgsujiaoxue.applinzi.com/index.php/Api/User/getInfo',

data: {

'openid': res.data.openid,

},

success:function (res1) {

wx.setStorageSync('userInfo', res1.data.data)

},

})


在myinfo.js文件的data数组中定义变量userinfo,并在onLoad()函数中对userinfo变量进行赋值,具体代码如下: 

Page({



/**

* 页面的初始数据

*/

data: {

userinfo:{ }

},



/**

* 生命周期函数--监听页面加载

*/

onLoad:function (options) {

this.setData({

userinfo: wx.getStorageSync('userInfo')

})

}

编译后发现头像显示过大,如图331所示。



图331头像显示过大


因此需要在媒体组件image中自定义类head_img,调整图片大小。其中myinfo.wxss文件的代码如下: 

.head_img{

height: 120rpx;

width: 120rpx;

border-radius: 50%;

}

到这里,“我的”页面就能正常显示了。
3.4作业思考
一、 讨论题
1. 讨论对小程序登录流程的理解。
2. 如何理解数据缓存中同步与异步缓存的区别?
3. 如何快速找到并使用WeUI基础样式库中自己需要的样式?
4. 样式中margin属性值为 0 auto是什么意思?
5.  bindchange与bindtap有什么区别?
6. 新建tabBar之后,register页面中页面跳转的逻辑是否需要修改?
7. 如何修改图片的大小和形状?
二、 单选题
1. wx.login()有()属性。

A. success、fail、timeout、complete
B. success、fail、data、complete
C. success、fail、timeout、data
D. success、fail、url、data
2. 以下关于wx.showModal()的说法错误的是()。
A. Title是模态对话框的标题
B. Content是模态对话框的内容
C. showCancel是否取消模态对话框
D. cancelText是“取消”按钮的文字
3. 以下关于wx.request()的说法不正确的是()。
A. URL是开发者服务器的接口地址
B. data是请求的参数
C. complete()是调用结束的回调函数(只有调用成功才会执行)
D. dataType默认值是json
4. 关于以下API请求的说法错误的是()。

wx.request({

url: ' https://zjgsujiaoxue.applinzi.com/index.php/Api/Weixin/code_to_openidv2',

data: {

questionA: right

},

success: function(res1) {

console.log('http返回值', res1)

},

fail: function(res2) {

console.log('http返回值', res2)

}

})

A. questionA:right表示向后台传送字符串'right'
B. console.log('http返回值',res1)表示请求成功打印后台返回值
C. console.log('http返回值',res2)表示请求失败打印后台返回值
D. 该请求的HTTP请求方式是POST 
5. 当wxml的input组件通过bindchange事件绑定了js的changname: function(e)函数时,打印input组件中改变的值,则使用()。
A. console.log(e.detail.value)
B. console.log(e.detail.input)
C. console.log(e.value)
D. console.log(e.input)
6. 以下关于 image组件的属性的说法中,()是错误的。
A. src: 图片的资源地址
B. mode: 图片裁剪、缩放的模式
C. binderror:当没有错误发生时,发布到AppService的事件名,事件对象event.detail={ errMsg: 'something wrong' }
D. bindload: 当文档载入完毕时,发布到AppService的事件名,事件对象event.detail={height:'图片高度px', width:'图片宽度px'}
7. 关于三目运算符的定义: <表达式1> ? <表达式2> : <表达式3>,以下表述正确的是()。
A. 先求表达式1的值,如果为真,则执行表达式2,并返回表达式2的结果
B. 先求表达式1的值,如果为真,则执行表达式3,并返回表达式3的结果
C. 如果表达式1的值为假,则执行表达式2,并返回表达式2的结果
D. 如果表达式1的值为真,则执行表达式2和3,并返回表达式2和3的结果
8. 以下关于rpx的说法正确的是()。
A. iPhone6上1rpx = 0.5px = 1物理像素
B. iPhone5上1rpx = 0.5px = 1物理像素
C. iPhone6上1rpx = 0.42px = 1物理像素
D. iPhone6 Plus上1rpx = 0.5px = 1物理像素
9. 以下关于borderradius的说法正确的是()。
A. 为图片添加边框B. 为图片添加圆角边框
C. 为文字添加圆角边框D. 为图片改变边框大小
10. 以下关于数据缓存API函数类型的说法不正确的是()。
A. wx.setStorage(Object object)实现数据的异步存储
B. wx.setStorage(Object object)实现数据的同步存储
C. wx.getStorage(Object object)实现数据的异步获取
D. wx.getStorageInfo(Object object)实现存储信息的异步获取