腾讯犀牛鸟云开发校园技术布道师养成计划第四天


生命周期

函数可以操作(增删改查)数据(包括字符串、数组、对象、Boolean等所有数据类型),组件拥有了属性数据,也就拥有了被编程的能力,可见携带数据的重要性(id、class、style甚至点击事件都是组件携带的数据,都可以用来编程)。

链接携带数据

URL链接的特殊字符

https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=云开发&rsv_pq=81ee270400007011&rsv_t=ed834wm24xdJRGRsfv7bxPKX%2FXGlLt6fqh%2BiB9x5g0EUQjyxdCDbTXHbSFE&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=20&rsv_sug1=19&rsv_sug7=100&rsv_sug2=0&inputT=5035&rsv_sug4=6227

这些链接通常包括以下特殊字符,以及都有着基本相同的含义,通过这些特殊字符,链接就被塞进了很多数据信息,其中?、&、=是我们接下来关注的重点。

  • / 分隔目录和子目录
  • ? 分隔实际的URL和参数
  • & URL中指定的参数间的分隔符
  • = URL中指定的参数的值
  • # 同一个页面的位置标识符,类似于页面的书签;

获取URL链接的数据

获取url参数的生命周期函数onload

onload是Page页面的生命周期函数,当页面加载时触发。一个页面只会调用一次,可以在 onLoad 函数的参数中获取打开当前页面路径中的参数。

{id: "lesson", uid: "tcb", key: "tap", ENV: "weapp", frompage: "lifecycle"}

相信大家会这样的数据类型非常熟悉,它就是一个对象Object,我们可以通过点表示法,获取到对象里具体的属性,比如options.id就能显示我们在lifecycle点击的组件的id。

数据跨页面

跨页面数据渲染

当然我们也可以继续把数据使用setData渲染到detail页面,为方便我们仅渲染图片信息

不过使用链接url传递参数有字节限制以及只能在跨页面中使用,但是可以用来传递比如页面链接来源,可以追踪用户来自于什么设备、什么App、通过什么方式以及来自哪个朋友的邀请链接;还可以用于一些网页链接的API必备的id、key等。跨多个页面以及传递更多参数、数据等,可以使用公共数据存储app.globalData(本节会介绍)、数据缓存(后面章节会介绍)、数据库(云开发部分会介绍)以及新增的页面间通信接口getOpenerEventChannel(这里不多介绍)

组件携带数据dataset

组件有公有属性和私有属性,这些属性都是数据,事件处理函数可以修改这些属性,从而让组件有丰富的表现形式。不仅如此,在组件节点中还可以附加一些自定义数据。在事件中可以获取这些自定义的节点数据,用于事件的逻辑处理,从而让组件变成相当复杂且强大的编程对象。

使用JavaScript代替Navigator组件

当我们点击lifecycle页面的图片时,clickImage会收到一个事件对象,打印出来的结果里包含着target和currentTarget两个属性,currentTarget指向事件所绑定的元素,而target始终指向事件发生时的元素。由于这个案例事件绑定的元素和事件发生时的元素都是imageclick,所以它们的值相同,它们里面都包含了当前组件的id,以及dataset

值得强调的是很多童鞋以为只有点击Navigator组件、button组件才能进行链接跳转,这是思维定势的误区,通过bindtap,组件被赋予了一定的编程能力,尽管没有url属性,使用wx.navigateTo也能具备这种能力。

我们点击的是图片image组件,却分别触发了绑定在image组件以及image的父级(上一级)组件view的事件处理函数,我们称这为事件冒泡

点击组件显示当前组件其他数据

通过事件对象我们不仅可以明确知道点击了什么组件,而且还可以获取当前组件的自定义数据。

小程序和页面的生命周期

小程序构造器:App(Object object)

页面构造器:Page(Object object)

打印日志了解生命周期

对小程序和页面的生命周期,我们可以通过打印日志的方式来了解生命周期函数具体的执行顺序和情况,使用开发者工具在app.js里给onLaunch、onShow、onHide添加一些打印日志。

onLaunch(opts) {
    console.log('onLaunch监听小程序初始化。',opts)
  },
  onShow(opts) {
    console.log('onShow监听小程序启动或切前台',opts)
  },
  onHide() {
    console.log('onHide监听小程序切后台')
  },

有的参数写的options,有的写的却是opts;前面事件对象有的写的是event,有的则用的是e,这个参数都是可以自定义的

小程序打开场景值

在 App 的 onLaunch 和 onShow打印的对象里有一个scene为1001,这个是场景值。场景值用来描述用户进入小程序的路径方式。用户进入你的小程序的方式有很多,比如有的是扫描二维码、有的是长按图片识别二维码,有的是通过微信群进入的小程序,有的是朋友单聊进入的小程序,有的是通过公众号进入的小程序等等,这些就是场景值,而具体的场景值,可以看技术文档,场景值对产品、运营来说非常重要。

技术文档:场景值列表

onLaunch与onShow

onLaunch是监听小程序的初始化,初始化完成时触发,全局只会触发一次,所以在这里我们可以用来执行获取用户登录信息的函数等一些非常核心的数据,如果onLaunch的函数过多,会影响小程序的启动速度。

onShow是在小程序启动,或从后台进入前台显示时触发,也就是它会触发很多次,在这里就不大适合放获取用户登录信息的函数啦。这两者的区别要注意。

用户登录与信息获取

小程序用户登录和获取用户信息相对来说比较复杂

了解wx.login、wx.getSetting

从控制台可以看到wx.login会得到errMsg和code,这个code是用户的登录凭证。而wx.getSetting则会得到errMsg和用户当前的权限设置authSetting,包含是否允许获取用户信息,是否允许获取用户位置,是否允许使用手机相册等权限。我们可以根据打印的结果结合技术文档来深入理解。

技术文档:获取用户登录凭证wx.login获取用户当前权限设置wx.getSetting

获取用户信息wx.getUserInfo

我们要获取用户信息,首先需要判断用户是否允许,可以从authSetting对象里看scope.userInfo属性是否为true,如果为true,那我们可以调用wx.getUserInfo()接口来获取用户信息。

globalData

globalData对象通常用来存放整个小程序都会使用到的数据,比如我们可以把用户信息赋值给globalData的任意自定义属性。

that与this

this的指向情况非常复杂,尽管哪个对象调用函数,函数里面的this就指向哪个对象,说起来非常简单,但是场景太多,大家在开发时不必强行理解,死记硬背,把this打印出来即可。

getApp()

那我们如何在页面的js里调用globalData呢,这个时候就需要用到getApp()函数啦。

技术文档:getApp()

通过button来获取用户信息

将用户信息写进app.js

这种方式只能在user页面才能获取到用户信息,限制非常大,那我们应该怎么做呢?我们要把获取到的用户信息写到app.js成为页面的公共信息,以后可以跨页面只需在user页面点击一次按钮即可。

在getUserInfomation将获取到的用户信息传给globalData的userInfo属性:

获取用户信息还有一种方式,就是通过组件open-data来展示,比较简单

数据表单

所用到的数据大多都是我们在js的data里写好的,无论是计算器、用户注册、表单收集、发表文章、评论等等,这些都是对用户提交数据的获取。

设置导航栏标题

动态设置导航栏标题是一个非常简单的API,在技术文档里面可以了解到,只要给wx.setNavigationBarTitle()的title对象赋值,就能改变小程序页面的标题。

技术文档:wx.setNavigationBarTitle()

onLoad调用API

button调用API

使用表单修改标题

小程序一个完整的数据表单收集通常包含一个form组件一个输入框或选择器组件(比如input组件),一个button组件

数据表单涉及到的组件多(至少三个),参数以及参数的类型也比较多,上面有几个非常重要的点,大家可以结合上面的代码来理解:

  • 表单最核心的在于表单组件form,输入框组件input和button组件要在
    内,form也会收集内部组件提交的数据;
  • 绑定事件处理函数的不再是button,而是form,form的bindsubmit与button的 formType=”submit”是一对,点击button,就会执行bindsubmit的事件处理函数;
  • input是输入框,用户可以在里面添加信息;name是input组件的名称,与表单数据一起提交。

对数据表单来说,使用console.log打印事件对象可以让我们对表单提交的数据有一个非常清晰的了解;而使用赋值以及setData可以有效的把表单收集到的数据渲染到页面。

文本输入框input

小程序的输入框input主要用来处理文本和数字的输入,下面我们就来结合实战与技术文档,来了解一下文本输入框input的type、name、placeholder等属性。

技术文档:input技术文档

使用开发者工具在form.wxml里输入以下代码,一个form组件里面可以包含多个选择器或文本输入框组件,提交数据时,会提交form里面填写的所有数据:

input输入框会因为属性的类型的不同,手机键盘外观会有比较大的差异,所以需要点击预览,用微信扫描二维码在手机上体验(也可以启用真机调试)。

  • input输入框支持的type值有文本输入text、数字输入number、身份证输入idcard、小数点输入digit,当type不同时,注意手机键盘外观的不同
  • placeholder:输入框为空时的占位符(也就是默认值);maxlength:最大输入长度;password和disabled都是boolean值,使用方法和之前的video组件里面的boolean属性一样。

在开发者工具的控制台我们可以看到打印的事件对象里的value对象,属性名即为input的name名,值即为我们输入的数据。如果没有name。

表单组件组合

一个完整的数据收集表单,除了可以提交input文本框里面的数据,还可以提交开关选择器按钮switch、滑动选择器按钮slider、单选按钮radio、多选按钮checkbox等组件里面的数据。

技术文档:switch开关选择Slider滑动选择Radio单选checkbox多选form表单

表单组件提交的数据都存储在事件对象e的detail属性下的value里.

  • switch属性:记录switch开关选择的值,这是一个boolean值,ture为开,false为关;

  • sex属性:记录name名为sex的单选按钮的值,它只记录单选选择的那一项的值;

  • process属性:

    记录name名为process的滑动选择器的值,

    show-value为boolean值,显示当前value值,数据类型为number;

  • textinput属性:记录name名为textinput的input文本输入框的值;

  • gamecheck属性:记录name名为gamecheck的多选组件的值,数据类型为数组Array

点击重置按钮,即会重置表单,并不需要formReset事件处理函数做额外的处理。

我们发现上面button属性,有时用的是form-type,有时用的是formType(注意两者的大小写),这两种写法都可以。我们也可以删掉重置的事件处理函数formReset,以及form组件的 bindreset=”formReset”,只需要将button的form-type设置为reset,也就是

<button form-type="reset">重置</button>

就可以达到重置的效果,绑定事件处理函数bindreset

数组的扩展运算符

在这里我们先来介绍一下扩展运算符的概念,它的写法很简单,就是三个点 ...

从控制台可以看到直接打印gamecheck,它是一个数组Array,中括号[ ]就可以看出来,展开也有index值;而使用扩展运算符打印gamecheck,是将数组里的值都遍历了出来。这就是扩展运算符…的作用

添加手机联系人

尽管我们提交了数据,但是当小程序重新编译之后,所有的数据都会被重置,也就是提交的数据并没有保存起来。小程序存储数据有三种方式,一是保存在本地手机上;二是存储到缓存里;三是存储到数据库。

添加手机通讯录联系人:wx.addPhoneContact()

对象的扩展运算符

对象的扩展运算符 …也有类型的作用,它可以取出对象里所有可遍历的属性,拷贝到新的对象中。

input绑定事件处理函数

在form表单里,尽管表单里也有input组件,但是绑定事件处理函数的是form组件,input组件只提供value值,而input文本输入组件本身也是可以绑定事件处理函数的。从技术文档里我们了解到input可以绑定事件处理函数的属性有:bindinput,键盘输入时触发;bindfocus,输入框聚焦时触发;bindblur,输入框失焦时触发等等

bindinput响应式数据渲染

剪贴板

本节前面的添加手机联系人是把收集到的数据存储到本地手机的通讯录里,而剪切板则是把数据存储到本地手机的剪切板里。

技术文档:设置剪切板内容wx.setClipboardData()获取剪切板内容wx.getClipboardData()

slider响应设置颜色

slider滑动选择器也可以绑定事件处理函数,有:bindchange完成一次拖动后触发的事件以及bindchanging拖动过程中触发的事件。

技术文档:滑动选择器slider

我们要先回顾一下事件对象里data-*携带的数据表单组件携带的数据:首先组件data-*属性的数据会存储在事件对象里的currentTarget下的dataset里的属性名里,也就是data-color的值会存储在 e.currentTarget.dataset.color里;而表单组件的数据则是存储在事件对象的detail里,也就是e.detail.value里。

picker组件

picker滚动选择器看起来样式非常复杂,不过小程序已经帮我们封装好了,我们只需要用几行简单的代码就可以做一个非常复杂而且类别多样的滚动选择器。

技术文档:滚动选择器picker

使用开发者工具在form.wxm里输入以下代码,只需要下面几行代码,就能从底部弹起一个日期的滚动选择器。而里面的文字可以任意填写,类似于button、navigator组件里的字,点击即可执行相应的事件。

<picker mode="date" value="{{pickerdate}}" start="2017-09-01" end="2022-09-01" bindchange="bindDateChange">
选择的日期为:{{pickerdate}}
</picker>
  • mode属性:滚动选择器有几种模式,不同的模式可以弹出不同类型的滚动选择器,这里的是date日期选择,其他模式大体相似;
  • start和end属性:这是日期选择器特有的属性,为有效日期的开始和结束,我们可以滚动试下,超出这个范围就没法滚动了;
  • 2020-03-20 21-31-30 的屏幕截图.png

图片、缓存与文件

获取手机相册里的图片和手机相机拍照的照片、手机的定位以及获取手机里的缓存、文件,并使用JavaScript操作图片、操作缓存和操作文件等。

获取手机相册或拍照的图片

用小程序来获取手机相册里的图片和拍照的照片听起来好像挺复杂的,不过因为有了API,我们只需要结合前面的点击事件、事件处理函数以及调用API、传入指定的参数就能很容易做到。

技术文档:wx.chooseImage()

上传一张照片

  • count:可以选择的照片数量,默认为9张(由于imgurl声明的是字符串,多张照片需为数组Array,后面有上传多张图片的案例)
  • sourceType:选择图片的来源,album就是图片可以来自手机相册;而camera是可以来自手机拍照,两个都写就是来自相册或拍照都可以;
  • sizeType:所选的图片的尺寸,original为原图,compressed为压缩图,为了减轻服务器压力,建议为压缩图;
  • tempFilePaths为临时文件的路径列表tempFiles为临时文件列表,注意这两个值都为数组。

空值的处理

我们可以看到由于imgurl为空值,image组件有默认宽度300px、高度225px(会随css而改变大小),所以显示上传的图片会与选择图片的button有一段空白,处理的方法有三种:

方法一:我们可以给imgurl弄一张初始图片的链接,为了让界面更加美观、交互性更好,通常都会设置一个默认的图片,比如默认的头像,当用户上传时,setData就会取代初始图片;

方法二:判断imgurl是否有内容,比如我们可以加一层逻辑判断,当Page()里的data下的imgurl属性非空时,组件才会显示;空时就不显示。

方法三:这个方法和方法二类似,设置一个逻辑判断

上传多张照片

如果上传的是多张照片,那么imgurl的初始值就不能是字符串了,而是一个数组Array,

操作图片

使用小程序图片API不仅可以上传图片,还可以对上传的图片进行一定的操作,比如获取图片信息、预览图片、保存图片、压缩图片等等。

获取图片信息

无论是存储在小程序本地,还是存储在临时文件、缓存、网络上的图片,使用wx.getImageInfo() 都可以获取到该图片的宽度、高度、路径、格式以及拍照方向。

技术文档:wx.getImageInfo()

回调函数

经过之前的学习,相信大家对回调函数success、fail有了一定的认识,那什么是回调函数呢?简单一点说就是:回调Callback是指在另一个函数执行完成之后被调用的函数。success、fail就都是在小程序的API函数执行完成之后,才会被调用,而success和fail它们本身也是函数,也能返回数据。而复杂一点说,就是回调函数本身就是函数,但是它们却被其他函数给调用,而调用函数的函数被称为高阶函数。这些大家只需要粗略了解就可以了。

异步与同步

我们前面也提及过异步,那什么会有异步呢?因为JavaScript是单线程的编程语言,就是从上到下、一行一行去执行代码,类似于排队一样一个个处理,第一个不处理完,就不会处理后面的。但是遇到网络请求、I/O操作(比如上面的读取图片信息)以及定时函数(后面会涉及)以及类似于成功反馈的情况,等这些不可预知时间的任务都执行完再处理后面的任务,肯定不行,于是就有了异步处理

把要等待其他函数执行完之后,才能执行的函数(比如读取图片信息)放到回调函数里,先不处理,等图片上传成功之后再来处理,这就是异步。比如wx.showToast()消息提示框,可以放到回调函数里,当API调用成功之后再来显示提示消息。回调函数相当于是异步的一个解决方案。

预览所有上传的图片

预览图片就是在新页面里全屏打开图片,预览的过程中用户可以进行保存图片、发送给朋友等操作。可以预览一张照片或者多张照片。

技术文档:wx.previewImage()

这个场景主要用于让用户可以预览、保存或分享图片,毕竟image组件是不支持图片的放大预览、保存到本地、转发给好友,现在微信还支持预览小程序码,长按就可以打开小程序,这个API主要是为了增强用户的交互体验的。

保存图片到相册

小程序不支持直接将网络图片保存到本地手机的系统相册,支持临时文件路径和小程序本地路径。

技术文档:wx.saveImageToPhotosAlbum()

当然永久链接实际开发用得不会太多,使用最多的场景是把网络图片下载到临时链接(因为不能直接保存网络图片),再将临时链接的图片保存到相册,只需把上面的永久链接换成临时链接就可以了.

压缩图片

小程序是有压缩图片的API的wx.compressImage(),尤其是在上传图片时,为了减轻存储服务器的压力,不能让用户上传分辨率过高的照片。

  • 可以先让用户上传图片;
  • 图片上传成功之后(也就是在上传图片的success回调函数里)再来获取图片的信息;
  • 获取信息成功后(也就是在获取图片信息的success回调函数里)判断宽度或高度是否过大,如果图片过大,就压缩图片,
  • 压缩图片成功后(也就是在压缩图片的success回调函数里),再把压缩好的图片上传到服务器

上传图片、获取图片信息、压缩图片、上传图片到服务器,每一步都依赖上一步,所以会不断在success回调函数里写函数,实际开发涉及的业务会更复杂,就会不断回调,这被称之为回调地狱

由于压缩图片使用到的场景不算太多,毕竟我们在上传照片时可以不支持上传原图original,只支持压缩compressed就能保证上传图片的大小了

上传文件

小程序不仅支持上传图片image,还支持上传视频、Excel、PDF、音频等等其他文件格式,但是我们只能从客户端会话里(也就是微信单聊、群聊的聊天记录里)选择其他格式的文件。

技术文档:wx.chooseMessageFile()

上传地理位置

除了可以上传图片、音视频以及各种文件格式以外,小程序还支持上传地理位置。

技术文档:wx.chooseLocation()

模块化与格式化

在新建模板小程序里(不使用云开发服务),有一个日志logs页面,这个日志logs虽然简单,但是包含着非常复杂的JavaScript知识,是一个非常好的学习参考案例,这里我们来对它进行一一解读。

模块化与引入模块

在实际开发中,日期、时间的处理经常会使用到,但是使用Date对象所获取到的时间格式与我们想要展现的形式是有非常大的差异的。这时我们可以把时间的处理抽离成为一个单独的 js 文件比如util.js(util是utility的缩写,表示程序集,通用程序等意思),作为一个模块。

把通用的模块放在util.js或者common.js,把util.js放在utils文件夹里等就跟把css放在style文件夹,把页面放在pages文件夹,把图片放在images文件夹里是一样的道理,尽管文件夹或文件的名称你可以任意修改,但是为了代码的可读性,文件结构的清晰,推荐大家采用这种一看就懂的方式。

数据缓存Storage

logs页面还涉及到数据缓存Storage方面的知识。通过前面的学习,我们了解到点击事件生成的事件对象也好,使用数据表单提交的数据也好,还是上传的图片、文件也好,只要我们重新编译小程序,这些数据都会消失。前面我们也提到存储数据、文件的方式有三种,一是保存到本地手机、二就是缓存,三是上传到服务器

技术文档:wx.setStorageSync()wx.getStorageSync()

保存文件

注意:尽管上传图片和上传文件都是把图片或文件先上传到临时文件里,但是保存图片wx.saveImageToPhotosAlbum()**和保存文件wx.saveFile()**是完全不同的概念,保存图片是把图片保存到手机本地相册;而保存文件则是把图片由临时文件移动到本地存储里,而本地存储每个小程序用户只有10M的空间。

保存文件技术文档:wx.saveFile()


文章作者: 毛雷
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 毛雷 !
评论
  目录