微信小程序学习笔记(二)-- 开发之框架

一、小程序框架介绍(了解)

小程序框架包含小程序的配置、框架接口、场景值、WXML 和 WXS 等

二、小程序的配置(精通)

小程序的配置分为全局配置、页面配置以及sitemap 配置

1、全局配置

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置。文件内容为一个 JSON 对象

img

下面介绍一下常用的配置选项

1.1 pages

用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对于位置的 .json, .js, .wxml, .wxss 四个文件进行处理

有多少个页面,此处就应该有多少个选项 数组的第一项代表小程序的初始页面(首页)。小程序中新增/减少页面,都需要对 pages 数组进行修改。

==开发小技巧==

直接在pages选项中写页面路径,即可创建相应的页面

默认项目如图所示

img

创建首页、分类、购物车、我的页面,编辑app.json中的pages选项如下

img

1.2 window

用于设置小程序的状态栏、导航条、标题、窗口背景色。

img

默认小程序展示如下

img

修改之后展示如下

img

各种属性展示示意图如下

img

1.3 tabBar

如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

img

其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:

img

其展示形式如下图所示

img

1.3.1 准备底部选项卡

  1. icon字体图标 在 iconfont字体图标库 中选择需要的图标,然后选择下载

修改相应的图片名字如下

2、项目目录下创建resource文件夹,将图片放置进去

5.jpg

3、app.json中配置底部选项卡

调整首页为第一个页面 --- 初始化页面

展示形式如下

1.4 networkTimeout

各类网络请求的超时时间,单位均为毫秒。

img

1.5 debug

可以在开发者工具中开启 debug 模式,在开发者工具的控制台面板,调试信息以 info 的形式给出,其信息有 Page 的注册,页面路由,数据更新,事件触发等。可以帮助开发者快速定位一些常见的问题

1.6 functionalPages

插件所有者小程序需要设置这一项来启用插件功能页

1.7 permission

小程序接口权限相关设置。字段类型为 Object,结构为:

img

PermissionObject 结构为

img

代码如下

1.jpg

展示效果如下

1.8 sitemapLocation

指明 sitemap.json 的位置;默认为 'sitemap.json' 即在 app.json 同级目录下名字的 sitemap.json 文件

1.9 navigateToMiniProgramAppIdList

当小程序需要使用 wx.navigateToMiniProgram 接口跳转到其他小程序时,需要先在配置文件中声明需要跳转的小程序 appId 列表,最多允许填写 10 个。

2、页面配置

每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项。文件内容为一个 JSON 对象,有以下属性

img

个人中心页面配置

img

3、sitemap 配置

小程序根目录下的 sitemap.json 文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有 sitemap.json ,则默认为所有页面都允许被索引。

三、框架接口(精通)

1.App(Object object)

注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

App() 必须在 app.js中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

img

示例中app.js代码如下

//app.js
App({
 onLaunch: function () {
 // 生命周期回调——监听小程序初始化 - 全局只触发一次
 // 展示本地存储能力
 var logs = wx.getStorageSync('logs') || []
 logs.unshift(Date.now())
 wx.setStorageSync('logs', logs)
​
 // 登录
 wx.login({
 success: res => {
 // 发送 res.code 到后台换取 openId, sessionKey, unionId
 }
 })
 // 获取用户信息
 wx.getSetting({
 success: res => {
 if (res.authSetting['scope.userInfo']) {
 // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
 wx.getUserInfo({
 success: res => {
 // 可以将 res 发送给后台解码出 unionId
 this.globalData.userInfo = res.userInfo
​
 // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
 // 所以此处加入 callback 以防止这种情况
 if (this.userInfoReadyCallback) {
 this.userInfoReadyCallback(res)
 }
 }
 })
 }
 }
 })
 },
 onShow(options) {
 // 小程序启动,或从后台进入前台显示时触发
 },
 onHide() {
 // 小程序从前台进入后台时触发.
 },
 onError(msg) {
 // 小程序发生脚本错误或 API 调用报错时触发
 console.log(msg)
 },
 onPageNotFound(res) {
 // 小程序要打开的页面不存在时触发;如果是 tabbar 页面,请使用 wx.switchTab - 404
 },
 globalData: {
 userInfo: null
 }
})

2.getApp(Object object)

获取到小程序全局唯一的 App 实例,在页面的js文件中获取

3.Page(Object object)

注册小程序中的一个页面。接受一个Object类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

img

以个人中心的js为例

// pages/user/user.js
Page({
​
 /**
 * 页面的初始数据
 * data 是页面第一次渲染使用的初始数据。
 * 页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。
 * 渲染层可以通过 WXML 对数据进行绑定。
 */
 data: {
​
 },
​
 /**
 * 生命周期函数--监听页面加载
 * 页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
 */
 onLoad: function (options) {
 // options为打开当前页面路径中的参数
 },
​
 /**
 * 生命周期函数--监听页面初次渲染完成
 * 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互
 */
 onReady: function () {
​
 },
​
 /**
 * 生命周期函数--监听页面显示
 *  页面显示/切入前台时触发
 */
 onShow: function () {
​
 },
​
 /**
 * 生命周期函数--监听页面隐藏
 * 页面隐藏/切入后台时触发
 */
 onHide: function () {
​
 },
​
 /**
 * 生命周期函数--监听页面卸载
 * 页面卸载时触发。
 */
 onUnload: function () {
​
 },
​
 /**
 * 页面相关事件处理函数--监听用户下拉动作
 * 需要在app.json的window选项中或页面配置中开启enablePullDownRefresh。
 * 可以通过wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
 * 当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新
 */
 onPullDownRefresh: function () {
​
 },
​
 /**
 * 页面上拉触底事件的处理函数
 * 可以在app.json的window选项中或页面配置中设置触发距离onReachBottomDistance。
 * 在触发距离内滑动期间,本事件只会被触发一次
 */
 onReachBottom: function () {
​
 },
​
 /**
 * 用户点击右上角分享
 */
 onShareAppMessage: function (res) {
 if (res.from === 'button') {
 // 来自页面内转发按钮
 console.log(res.target)
 }
 // 自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4。
 return {
 title: '自定义转发标题',
 path: '/page/user?id=123',
 imageUrl: ''
 }
 },
​
 /**
 * 监听用户滑动页面事件
 */
 onPageScroll: function () {
​
 }
 /**
 * 自定义函数
 */
})

4、getCurrentPages()

获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。

不要尝试修改页面栈,会导致路由以及页面状态错误。 不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成。

5、自定义组件

创建自定义组件,接受一个 Object 类型的参数

比如在首页里需要一个产品列表的组件,可以自定义该组件

小技巧 点击 “+”选择目录,输入components

右键点击components目录,选择目录, 输入prolist

右键点击prolist目录,选择 新建Component ,输入prolist 即可

如何使用该组件呢?

在首页的pages/home/home.json文件中注册组件

在首页的pages/home/home.wxml中使用该组件,就像正常的标签一样使用

组件之间的传值在后续课程中会讲解

6、模块化

建议使用es6的模块化方法,api中提供的是基于commonjs规范的exports以及require语法

6.1 定义工具模块 utils/index.js

数据请求模块 以及 可消失的提示框 模块 - 暴露

const baseUrl = 'http://daxun.kuboy.top'
/**
 * 数据请求模块
 * 接口地址 http://daxun.kuboy.top/apidoc
 * 先显示加载框,然后请求结束加载框消失
 * 
 */
export function request (url, data) {
 // 显示加载中
 // 参考https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showLoading.html
 wx.showLoading({
 title: '加载中',
 })
 // 使用promise 解决异步操作问题,此处还可以使用 async + await
 return new Promise((resolve, reject) => {
 // 微信小程序的数据请求方法
 // 必须配置小程序的安全域名,
 // 在开发阶段可以在“详情” - “本地设置” - 勾选中 不校验请求域名、web-view(业务域名)、TLS版本及HTTPS证书
 wx.request({
 url: baseUrl + url,
 data: data || {},
 success: (res) => {
 // 隐藏加载中
 wx.hideLoading();
 // 后续处理
 resolve(res.data)
 }
 })
 })
}
​
/**
 * 可消失的提示框 - 默认只显示文字
 * str 提示内容
 * icon 是否需要图标,none 、 success(默认值) 、 loading
 */
export function Toast (str, icon) {
 // 微信提供的API接口
 // 参照 https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showToast.html
 wx.showToast({
 title: str,
 icon: icon || 'none'
 })
}

6.2 首页中测试

在首页 pages/home/home.js中测试,先引入模块

img

四、WXML语法参考(精通)

创建一个新的页面pages/test/test

img

选择工具栏的 小程序编译,添加编译模式,可以更快捷的只渲染本页面,便于开发者的调试

1.数据绑定

WXML 中的动态数据均来自对应 Page 的 data。

1.简单绑定(类似于vue中的Mustache 语法)

数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:

内容

<view> {{ message }} </view>
Page({
 data: {
 message: 'Hello MINA!'
 }
})
  1. 组件属性(需要在双引号之内)
<view id="item-{{id}}"> </view>
Page({
 data: {
 id: 0
 }
})
img

3.控制属性(需要在双引号之内)

<view wx:if="{{flag}}"> 条件为真我就显示 </view>
Page({
 data: {
 flag: true
 }
})

4.boolean以及number数据类型

如果数据类型是booblean 或者number类型的数据,需要使用{{}}包裹

<checkbox checked="{{false}}"> </checkbox>
<view data-num = "{{100}}"></view>
img

5.表达式运算 可以在 {{}} 内进行简单的运算,支持三元运算、算数运算、逻辑判断、字符串运算等

<view test="{{flag ? true : false}}"> 属性 </view>
​
<view> {{a + b}} + {{c}} + d </view>
​
<view wx:if="{{len > 5}}"> </view>
​
<view>{{"hello" + name}}</view>

2.列表渲染

wx:for(vue中使用v-for)

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。

默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

列表渲染必须添加 wx:key指令, 来指定列表中项目的唯一的标识符。

key值可以设置为索引值

Page({
 data: {
 teachers: [
 {
 name: '刘沛君',
 city: '大连'
 },
 {
 name: '韦华文',
 city: '长沙'
 },
 {
 name: '卢有烨',
 city: '重庆'
 },
 {
 name: '刘春华',
 city: '北科'
 },
 {
 name: '黄俊健',
 city: '北科'
 },
 {
 name: '谢晋荣',
 city: '广州'
 },
 {
 name: '李威',
 city: '深圳'
 },
 {
 name: '李鹏',
 city: '郑州'
 },
 {
 name: '赵小康',
 city: '南京'
 },
 {
 name: '张路',
 city: '成都'
 },
 {
 name: '李响',
 city: '合肥'
 },
 ]
 }
})
​
<view wx:for="{{teachers}}" wx:key="index">
 <text>{{index}}</text>
 -
 <text>{{item.city}}</text>
 -
 <text>{{item.name}}</text>
</view>

默认 选项为item,默认索引值为index,如果需要更改,可以使用如下方式

<view wx:for="{{teachers}}" wx:for-item="itm" wx:for-index="idx"  wx:key="idx">
 <text>{{idx}}</text>
 -
 <text>{{itm.city}}</text>
 -
 <text>{{itm.name}}</text>
</view>

3.条件渲染

wx:if 在框架中,使用 wx:if="" 来判断是否需要渲染该代码块

<view wx:if="{{flag}}"> True </view>

也可以用 wx:elif 和 wx:else 来添加一个 else 块

<view wx:if="{{len > 5}}"> 1 </view>
<view wx:elif="{{len > 2}}"> 2 </view>
<view wx:else> 3 </view>

因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性

<block wx:if="{{true}}">
 <view> view1 </view>
 <view> view2 </view>
</block>

==注意==: <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

wx:if vs hidden --- (对比vue中的 v-if 与 v-show)

因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。

同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。

相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。

一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好

五、WXS语法(了解)

WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。

WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。

熟悉js语法的可以很快速的接收并且掌握它。

六、WXSS语法

WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。

WXSS 用来决定 WXML 的组件应该怎么显示。

为了适应广大的前端开发者,WXSS具有CSS大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。

与 CSS 相比,WXSS 扩展的特性有:

尺寸单位

样式导入

1.尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素

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

2.样式导入

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束

3.全局样式与局部样式

定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339