带你读《微信小程序商城开发:界面设计实战》之二:小程序基础知识

丰富的线上&线下活动,深入探索云世界

做任务,得社区积分和周边

最真实的开发者用云体验

让每位学生受益于普惠算力

让创作激发创新

资深技术专家手把手带教

遇见技术追梦人

技术交流,直击现场

海量开发者使用工具、手册,免费下载

极速、全面、稳定、安全的开源镜像

开发手册、白皮书、案例集等实战精华

为开发者定制的Chrome浏览器插件

可以在项目根目录使用project.config.json文件(参见1.3.1节)对项目进行配置,项目配置文件的内容参见表2-1。

表2-1项目配置文件

其中,compileType的有效值如下。

{"packOptions":{"ignore":[{"type":"file","value":"test/test.js"},{"type":"folder","value":"test"},{"type":"suffix","value":".webp"},{"type":"prefix","value":"test-"},{"type":"glob","value":"test/**/*.js"},{"type":"regexp","value":"\\.jsx$"}]}}这部分设置的更改可能需要重新打开项目才能生效。debugOptions用于配置在对项目代码进行调试时的选项。目前可以指定debugOptions.hidedInDevtools字段,用于配置是否显示调试器的源代码。hidedInDevtools的配置规则和packOptions.ignore是一致的。当某个.js文件符合此规则时,调试器Sources面板中此文件源代码正文内容将被隐藏,显示代码示例如下:

//xxx.jshasbeenhidedbyproject.config.json注:配置此规则后,可能需要关闭并重新打开项目才能看到效果。项目配置代码示例如下:

{"pages":["pages/index/index","pages/logs/index"],"window":{"navigationBarTitleText":"Demo"},"tabBar":{"list":[{"pagePath":"pages/index/index","text":"首页"},{"pagePath":"pages/logs/logs","text":"日志"}]},"networkTimeout":{"request":10000,"downloadFile":10000},"debug":true,"navigateToMiniProgramAppIdList":["wxe5f52902cf4de896"]}app.json配置项列表参见表2-2。

表2-2app.json配置项列表

{"pages":["pages/index/index","pages/logs/logs"]}(2)windowwindow用于设置小程序的状态栏、导航条、标题、窗口背景色等,属性参见表2-3。

表2-3window属性

app.json示例代码如下,界面示例如图2-1所示:

表2-4tabBar属性

图2-2list属性示例

表2-5networkTimeout属性

每一个小程序的页面可以使用.json文件对本页面的窗口表现进行配置。页面配置只能设置app.json中部分window配置项的内容,页面中配置项会覆盖app.json的window中相同的配置项,页面配置属性参见表2-6。配置样例代码如下:

表2-6页面配置属性

/**common.wxss**/.small-p{padding:5px;}/**app.wxss**/@import"common.wxss";.middle-p{padding:15px;}3.全局样式与局部样式定义在app.wxss中的样式为全局样式,作用于每一个页面。在page的.wxss文件中定义的样式为局部样式,只作用于对应的页面,并会覆盖app.wxss中相同的选择器。4.内联样式框架组件上支持使用style和class属性来控制组件的样式,说明如下。

小程序框架的逻辑层并非运行在浏览器中,因此JavaScript在Web中的一些能力无法使用,如window、document等。

小程序的App方法包含一系列函数,例如:App(Object)、onLaunch(Object)、on-Show(Object)、onHide()、onError(Stringerror)、onPageNotFound(Object)、getApp(Object)等。1.App(Object)App()函数用来注册一个小程序。接受一个Object参数,指定小程序的生命周期回调等。App()必须在app.js中调用且只能调用一次,否则会出现无法预期的后果。Object参数说明参见表2-7。

表2-7App()函数的Object参数表

App({onLaunch:function(options){//Dosomethinginitialwhenlaunch.},onShow:function(options){//Dosomethingwhenshow.},onHide:function(){//Dosomethingwhenhide.},onError:function(msg){console.log(msg)},globalData:'Iamglobaldata'})2.onLaunch(Object)onLaunch()函数在小程序初始化完成时触发,全局只触发一次,其中,Object参数说明参见表2-8。

表2-8onLaunch()函数的Object参数表

其中,referrerInfo.appId场景值参见表2-9。

表2-9referrerInfo.appId场景值

//other.jsvarappInstance=getApp()console.log(appInstance.globalData)//Iamglobaldata不要在定义于App()内的函数中调用getApp(),使用this就可以获取App实例。通过getApp()获取实例之后,不要私自调用生命周期函数。

当前支持的场景值参数见表2-10。基础库1.1.0开始支持,低版本需做兼容处理。

表2-10场景值参数

小程序的Page方法用于页面的注册和配置。1.页面Page()函数Page()函数用来注册一个页面。接受一个Object类型参数,指定页面的初始数据、生命周期回调、事件处理函数等。Object参数说明参见表2-11。

表2-11Page()函数的Object参数

Page({onTabItemTap(item){console.log(item.index)console.log(item.pagePath)console.log(item.text)}})5.组件事件处理函数Page中还可以定义组件事件处理函数。在渲染层的组件中加入事件绑定,当事件被触发时,执行Page中定义的事件处理函数。代码示例如下:

clickmePage({viewTap:function(){console.log('viewtap')}})6.routePage.route表示到当前页面的路径,类型为String,基础库1.2.0开始支持,低版本需做兼容处理。代码示例如下:

代码示例如下:

图2-3Page实例的生命周期

在小程序中,所有页面的路由全部由框架进行管理。框架以栈的形式维护了当前的所有页面。当发生路由切换的时候,页面栈的表现如表2-12所示。

getCurrentPages()函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。不要尝试修改页面栈,会导致路由以及页面状态错误。不要在App.onLaunch的时候调用getCurrentPages(),此时page还没有生成。路由的触发方式以及页面生命周期函数参见表2-13。

表2-13路由的触发方式以及页面生命周期函数

//common.jsfunctionsayHello(name){console.log(`Hello${name}!`)}functionsayGoodbye(name){console.log(`Goodbye${name}!`)}module.exports.sayHello=sayHelloexports.sayGoodbye=sayGoodbye在需要使用这些模块的文件中,使用require(path)将公共代码引入,代码示例如下:

varcommon=require('common.js')Page({helloMINA:function(){common.sayHello('MINA')},goodbyeMINA:function(){common.sayGoodbye('MINA')}})require暂时不支持绝对路径。

wx.login({success(res){console.log(res.code)}})2.5WXML视图层开发WXML(WeiXinMarkupLanguage)是框架设计的类似于HTML的标签语言,结合基础组件、事件系统就可以构建出页面的结构,组成.wxml文件。WXML中的动态数据均来自对应Page的data。本节主要讲解视图层开发中.wxml文件常用的语法,包含数据绑定、列表渲染、条件渲染、模板、事件、引用等处理。

数据绑定是指在小程序的.js文件里,将data定义的各类数据显示在.wxml页面中。当然data里面定义的各类数据可以通过其他方式进行变更。1.简单绑定数据简单绑定是指使用Mustache语法(双大括号)将变量包起来。.wxml文件代码示例如下:

{{message}}.js文件代码示例如下:

Page({data:{message:'HelloMINA!'}})组件属性需要在双引号之内,.wxml文件代码示例如下:

.js文件代码示例如下:Page({data:{id:0}})控制属性需要在双引号之内,.wxml文件代码示例如下:

.js文件代码示例如下:Page({data:{condition:true}})关键字(需要在双引号之内)包括。

.wxml文件代码示例如下:

不要直接写checked="false",其计算结果是一个字符串,转成boolean类型后代表真值。2.运算可以在{{}}内进行简单的运算,支持如下几种运算:三元运算,.wxml文件代码示例如下:

Hidden算数运算,.wxml文件代码示例如下:

{{a+b}}+{{c}}+d.js文件代码示例如下:

Page({data:{a:1,b:2,c:3}})view中的内容为3+3+d。逻辑判断,.wxml文件代码示例如下:

5}}">字符串运算,.wxml文件代码示例如下:

{{"hello"+name}}.js文件代码示例如下:

Page({data:{name:'MINA'}})数据路径运算,.wxml文件代码示例如下:

{{object.key}}{{array[0]}}.js文件代码示例如下:

Page({data:{object:{key:'Hello'},array:['MINA']}})3.组合也可以在Mustache内直接进行组合,构成新的数组或者对象。(1)数组.wxml文件代码示例如下:

{{item}}.js文件代码示例如下:

Page({data:{zero:0}})最终组合成数组[0,1,2,3,4]。(2)对象.wxml文件代码示例如下:

.js文件代码示例如下:

Page({data:{a:1,b:2}})最终组合成对象{for:1,bar:2}。也可以用扩展运算符...将一个对象展开。.wxml文件代码示例如下:

.js文件代码示例如下:

Page({data:{obj1:{a:1,b:2},obj2:{c:3,d:4}}})最终组合成对象{a:1,b:2,c:3,d:4,e:5}。如果对象的key和value相同,也可以间接地表达。.wxml文件代码示例如下:

.js文件代码示例如下:

Page({data:{foo:'my-foo',bar:'my-bar'}})最终组合成对象{foo:'my-foo',bar:'my-bar'}。上述方式可以随意组合,但如存在变量名相同的情况,后边的会覆盖前面的,如:

Page({data:{obj1:{a:1,b:2},obj2:{b:3,c:4},a:5}})最终组合成的对象是{a:5,b:3,c:6}。花括号和引号之间如果有空格,将最终被解析成字符串。.wxml文件代码示例如下:

{{item}}等同于代码:

{{item}}2.5.2列表渲染列表渲染是指,在小程序.js文件里,把data定义的数组数据通过for循环语句显示在.wxml页面中。当然data里面定义的各类数据可以通过其他方式进行变更。在实际的应用中,通过列表渲染可以输出产品列表、新闻列表等。1.wx:for在组件上使用wx:for控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item,.wxml文件代码示例如下:

{{index}}:{{item.message}}.js文件代码示例如下:Page({data:{array:[{message:'foo',},{message:'bar'}]}})使用wx:for-item可以指定数组当前元素的变量名,使用wx:for-index可以指定数组当前下标的变量名,.wxml文件代码示例如下:

{{idx}}:{{itemName.message}}wx:for也可以嵌套,下面是一个九九乘法表的.wxml文件代码示例:

{{i}}*{{j}}={{i*j}}2.blockwx:for可以将wx:for用在标签上,以渲染一个包含多节点的结构块。.wxml文件代码示例如下:

{{index}}:{{item}}并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。3.wx:key如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如中的输入内容,的选中状态),需要使用wx:key来指定列表中项的唯一标识符。wx:key的值有以下两种形式。

{{item.id}}SwitchAddtothefront{{item}}Addtothefront.js文件代码示例如下:

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:function(e){constlength=this.data.objectArray.lengthfor(leti=0;i

{{item}}等同于:

{{item}}花括号和引号之间如果有空格,将最终被解析成字符串,.wxml文件代码示例如下:

{{item}}等同于:

{{item}}2.5.3条件渲染条件渲染是指,根据if语句中的条件来决定if语句所在区块是显示还是隐藏,如果if条件语句为True,则渲染显示;如果if条件语句为False,则隐藏不做渲染显示。在实际开发中,可以通过按钮来改变if条件语句的变量状态(True和False之间转换)来实现某个区块的显示或隐藏。1.wx:if在框架中,使用wx:if="{{condition}}"来判断是否需要渲染该代码块,.wxml文件代码示例如下:

True也可以用wx:elif和wx:else来添加一个else块,.wxml文件代码示例如下:

5}}">12}}">232.blockwx:if因为wx:if是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个标签将多个组件包装起来,并在上边使用wx:if控制属性,.wxml文件代码示例如下:

view1view23.wx:ifvshidden因为wx:if之中的模板也可能包含数据绑定,所以当wx:if的条件值切换时,框架有一个局部渲染的过程,以确保条件块在切换时销毁或重新渲染。同时,wx:if也是惰性的,如果初始渲染条件为False,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。相比之下,hidden就简单多了,组件始终会被渲染,只是简单地控制显示与隐藏。一般来说,wx:if有更高的切换消耗,而hidden有更高的初始渲染消耗。因此,在需要频繁切换的情景下,用hidden更好;而在运行时条件不大可能改变时,则用wx:if较好。

模板用于将一些公用的WXML代码单独整理成一个.wxml文件,然后在有需要的地方直接引入即可。可以在模板中定义代码片段,然后在不同的地方调用。1.定义模板使用name属性作为模板的名字,然后在

even模板拥有自己的作用域,只能使用data传入的数据以及模板定义文件中定义的模块。

事件是控件可以识别的操作,如按下某个按钮,选择某个复选框。每一种控件有自己可以识别的事件,如小程序页面的加载、按钮的单击、表单的提交等事件,也包括编辑框(文本框)的文本改变事件等。事件有如下特征:

1.事件的使用方式在组件中绑定一个事件处理函数,如bindtap,当用户点击该组件的时候,会在该页面对应的Page中找到相应的事件处理函数,.wxml文件代码示例如下:

Clickme!在相应的Page定义中写入相应的事件处理函数,参数是event,.js文件代码示例如下:

Page({tapName:function(event){console.log(event)}})可以看到,log出来的信息大致如下:

{"type":"tap","timeStamp":895,"target":{"id":"tapTest","dataset":{"hi":"WeChat"}},"currentTarget":{"id":"tapTest","dataset":{"hi":"WeChat"}},"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}]}2.事件分类事件分为冒泡事件和非冒泡事件。

WXML的冒泡事件参见表2-14。

表2-14WXML的冒泡事件列表

bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。例如,在下面这个例子中,点击innerview会依次调用handleTap3和handleTap2(因为tap事件会冒泡到middleview,而middleview阻止了tap事件冒泡,不再向父节点传递),点击middleview会触发handleTap2,点击outerview会触发handleTap1,.wxml文件代码示例如下:

outerviewmiddleviewinnerview4.事件的捕获阶段自基础库版本1.5.0起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。在下面的.wxml文件代码中,点击innerview会依次调用handleTap2、handleTap4、handleTap3、handleTap1:

outerviewinnerview如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2。.wxml文件代码示例如下:

DataSetTest.js文件代码示例如下:

WXML提供两种文件引用方式:import和include。1.importimport可以在该文件中使用目标文件定义的template,例如,在item.wxml中定义了一个名为item的template,.wxml文件代码示例如下:

{{text}}在index.wxml中引用了item.wxml,就可以使用item模板,.wxml文件代码示例如下:

import有作用域的概念,即只输入目标文件中定义的模板,而不输入目标文件自己输入的模板。例如,CimportB,BimportA,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template。.wxml文件代码示例如下:

Atemplate.wxml文件代码示例如下:

Btemplate.wxml文件代码示例如下:

2.includeinclude可以将目标文件除