第3讲 小程序框架(小程序框架结构)
ccwgpt 2024-09-23 04:40 141 浏览 0 评论
「遇见周大侠(网名:程序猿),长沙奥科领航信息技术公司的资深软件开发工程师。他的软件开发系列课件和项目,凝聚了多年的专业积累与热情。每套课件都包含丰富的案例和深入的知识点解析,每一讲都配备了精心设计的课后作业,旨在为热爱编程的你提供最佳编程实践。是教师备课的得力助手,是学生学习的贴心伴侣,亦是毕业设计的灵感源泉。现在,请搜索微信小程序「奥科领航信息技术 」,让我们一起深入代码的世界,探索无限可能!」
目录:
- 小程序框架
- 逻辑层
- 视图层
一、小程序框架
1.1 框架概述
小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。
整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)。小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
1.2 数组绑定
同学们,还记得Vue(实现了MVVM设计模式)中的数据绑定吗?在Vue中,表单元素和模型实现了双向的数据绑定,当一端发生改变,另一端会同步改变。微信小程序也实现了类似的功能!
微信小程序框架的核心是一个响应式的数据绑定系统,可以让数据与视图非常简单地保持同步。当做数据修改的时候,只需要在逻辑层修改数据,视图层就会做相应的更新。
示例1:在index页面的一个view标签中显示一个默认的字符串“我爱你”,点击[确定]按钮,view标签显示为“我恨你”。
<!-- index.wxml -->
<!-- 以文本插值{{}}的方式显示数据 -->
<!-- view标签相当于HTML中的div -->
<view>{{message}}</view>
<!-- 定义一个按钮 -->
<!-- bind:tap事件相当于HTML中的click。changeValue是一个自定义的事件处理函数名称 -->
<!-- bind:tap可以写成bindtap -->
<button type="primary" bind:tap="changeValue">修改值</button>
// index.js
// Page是页面的入口函数
Page({
// 在data选项中定义数据
data: {
message: "我爱你"
},
// 定义函数
changeValue: function () {
// setData()函数的作用:修改data选项中所定义的数据
// 要修改data选项中所定义的数据,只能通过调用setData()函数来实现!
this.setData({
message: "我恨你"
})
}
})
代码说明:
- 我们通过框架将逻辑层数据中的 message与视图层的 message进行了绑定,所以在页面一打开的时候会显示“我爱你”;
- 当点击按钮的时候,触发bindtap事件,视图层会发送 changeValue 给逻辑层,逻辑层找到并执行对应的事件处理函数;
- 回调函数触发后,逻辑层执行 setData 的操作,将 data 中的 message从“我爱你” 变为“我恨你”,因为该数据和视图层已经绑定了,从而视图层会自动改变为“我恨你”!
小结:
- 点击命令按钮,会触发bindtap事件。bindtap事件相当于HTML标签的onclick事件。bindtap可以写成bind:tap
- 要修改data中的属性值,必须通过调用setData()函数来修改。
示例2:在文本框中输入值,在view中同步显示。
<!-- index.wxml -->
<!-- 定义一个文本框 -->
<!-- 在文本框中每输入一个字符,都会触一次bindinput事件 -->
<input type="text" bindinput="changeValue" placeholder="请输入值"/>
<view>{{message}}</view>
// index.js
Page({
data: {
message: ""
},
// 定义函数
// 参数e代表一个事件对象,里面封装了本次事件触发之后所产生的一些数据
changeValue: function(e){
// e.detail.value:获取文本框中的值
// detail:详细;value:值
console.log(e);
console.log(e.detail.value);
this.setData({
message: e.detail.value
})
}
})
小结:在文本框中输入文字,会触发bindinput事件。bindinput事件相当于HTML中的oninput事件。
1.3 页面管理
框架管理了整个小程序的页面路由,可以做到页面间的无缝切换,并给以页面完整的生命周期。开发者需要做的只是将页面的数据、方法、生命周期函数注册到框架中,其他的一切复杂的操作都交由框架处理。
1.4 基础组件
框架提供了一套基础的组件,这些组件自带微信风格的样式以及特殊的逻辑,开发者可以通过组合基础组件,创建出强大的微信小程序。
见官网:
https://developers.weixin.qq.com/miniprogram/dev/component/
1.5 丰富的API
框架提供丰富的微信原生API,可以方便的调起微信提供的能力,如获取用户信息、本地存储、支付功能等。
见官网:
https://developers.weixin.qq.com/miniprogram/dev/api/
二、逻辑层
2.1 注册小程序
每个小程序都需要在 app.js 中调用 App() 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。
App() 必须在 app.js 中调用,必须调用且只能调用一次,不然会出现无法预期的后果。
App({
...
});
各个回调函数及其说明请见官方文档:
https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html
2.2 注册页面
对于小程序中的每个页面,都需要在页面对应的 js 文件中进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。
Page({
...
});
请见官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html
2.3 页面生命周期
onLoad->onShow->onReady->onHide->onUnload
2.4 页面路由
从一个页面跳转到另一个页面,叫做页面路由。
页面路由有四个API:
- navigateTo:导航
- redirectTo:重定向
- switchTab:切换Tab页面
- reLauhc:重启
见官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html
2.4.1 示例1
默认显示首页(index),然后点击底部导航的日志(log),观察各个生命周期函数的输出信息。
2.4.1.1 准备工作
(1)app.json
{
"pages": [
"pages/index/index",
"pages/logs/logs",
"pages/orders/orders",
"pages/cart/cart",
"pages/home/home",
"pages/a/a"
],
"window": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "中华人民共和国",
"navigationBarBackgroundColor": "#0000ff"
},
"style": "v2",
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents",
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "./images/1.png",
"selectedIconPath": "./images/1_1.png"
},{
"pagePath": "pages/logs/logs",
"text": "日志",
"iconPath": "./images/2.png",
"selectedIconPath": "./images/2_2.png"
},{
"pagePath": "pages/orders/orders",
"text": "我的订单",
"iconPath": "./images/3.png",
"selectedIconPath": "./images/3_3.png"
},{
"pagePath": "pages/cart/cart",
"text": "购物车",
"iconPath": "./images/4.png",
"selectedIconPath": "./images/4_4.png"
}]
}
}
(2)index.js
Page({
onReady: function(){
console.log("index:ready函数执行了");
},
onUnload: function(){
console.log("index:unload函数执行了");
},
onLoad: function(){
console.log("index:load函数执行了");
},
onShow: function(){
console.log("index:show函数执行了");
},
onHide: function(){
console.log("index:hide函数执行了");
}
})
(3)logs.js
Page({
onReady: function(){
console.log("logs:ready函数执行了");
},
onUnload: function(){
console.log("logs:unload函数执行了");
},
onLoad: function(){
console.log("logs:load函数执行了");
},
onShow: function(){
console.log("logs:show函数执行了");
},
onHide: function(){
console.log("logs:hide函数执行了");
}
})
(4)a.js
Page({
onReady: function(){
console.log("a:ready函数执行了");
},
onUnload: function(){
console.log("a:unload函数执行了");
},
onLoad: function(){
console.log("a:load函数执行了");
},
onShow: function(){
console.log("a:show函数执行了");
},
onHide: function(){
console.log("a:hide函数执行了");
}
})
2.4.1.1 控制台输出
(1)初始显示首页的输出
(2)切换到底部tab栏的日志的输出
从输出结果可知,原来的首页只是被隐藏了,并没有被卸载。
(3)再切换到首页
2.4.2 示例2
从首页导航到A页面。
// index.js
Page({
...
navigateToA: function(){
// 通过导航的方式进行页面路由
wx.navigateTo({
url: '../a/a',
})
},
})
<!-- index.wxml -->
<button type="primary" bind:tap="navigateToA">导航到A页面</button>
2.4.2 示例3
从首页重定向到A页面。
// index.js
Page({
...
redirectToA: function(){
// 通过导航的方式进行页面路由
wx.redirectTo({
url: '../a/a',
})
},
})
<!-- index.wxml -->
...
<button type="primary" bind:tap="redirectToA">重定向到A页面</button>
更加详细的路由资料见"小程序路由小结.md"文档。
2.5 API
见官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/api.html#API
前面我们已经用到了wx.navigateTo()、wx.redirectTo()、wx.navigateBack()、wx.switchTab()等API。现在我再举一个获取用户信息API。先看效果:
<!-- index.wxml -->
<view class="tip">首页</view>
<button type="primary" bindtap="getUserInfo">获取用户信息</button>
<view>{{userInfo.nickName}}</view>
<view wx:if="{{userInfo.gender}}">{{userInfo.gender == 1? "男" : "女"}}</view>
<image src="{{userInfo.avatarUrl}}"></image>
// index.js
Page({
data: {
userInfo: {}
},
getUserInfo: function(e){
wx.getUserProfile({
desc: "用于完善用户资料",
success: (res) => {
console.log(res.userInfo);
this.setData({
userInfo: res.userInfo
});
}
})
}
})
点击模拟器中的【获取用户信息】按钮,没有显示像上图中那样的底部弹框,在控制台输出的用户信息如下:
这是因为从2022年10月26日开始,wx.getUserProfile接口被收回了:
如果将基础库版本调整为2.21.2或者以下,则可以。
三、视图层
框架的视图层由 WXML 与 WXSS 编写。
将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。
- WXML(WeiXin Markup language) 用于描述页面的结构。
- WXSS(WeiXin Style Sheet) 用于描述页面的样式。
3.1 wxml
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
3.1.1 数组绑定
语法:{{}}
// index.js
Page({
data: {
message: "初始值"
}
})
<!-- index.wxml -->
<view>{{message}}</view>
3.1.2 条件渲染
语法:wx:if、wx:elif、wx:else
// index.js
Page({
data: {
week: (new Date()).getDay()
}
})
<!-- index.wxml -->
<view wx:if="{{week >= 1 && week <= 5}}">
星期一到星期五,学习时间
</view>
<view wx:elif="{{week == 6}}">
星期六,购物时间
</view>
<view wx:else>
星期天,休息时间
</view>
3.1.3 列表渲染
语法:wx:for
// index.js
Page({
data: {
students: [{id: 10001, name: "张三"}, {id: 10002, name: "李四"}]
}
})
<!-- index.wxml -->
<block wx:for="{{students}}">
<view style="border-bottom: 1px solid #000000">
<view>序号:{{index}}</view>
<view>编号:{{item.id}}</view>
<view>姓名:{{item.name}}</view>
</view>
</block>
代码说明:
- <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。在上面的例子中,也可以直接将wx:for写在应用了样式的那个view上;
- 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为item;
- 使用 wx:for-item 可以指定数组当前元素的变量名;
- 使用 wx:for-index 可以指定数组当前下标的变量名;
课堂练习:渲染出一个九九乘法口诀表。
<block wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="i">
<view>
<block wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="j">
<text>{{i}} * {{j}} = {{i * j}}</text>
</block>
</view>
</block>
关于wxk:key的说明。官方解释:当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。通俗的理解:在不使用 wx:key的情况下, 如果 array 内的数据发生改变,则会重新创建每个Item对象然后渲染列表,费时费力。而在使用 wx:key的情况下,如果array中的数据发生改变,只是将对应的对象重新排序。未发生变化的对象,不会重新创建。有两种使用方法:
- 第一种:wx:key = “字符串或数字”,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 第二种:保留关键字 *this,代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
3.2 wxss
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位尽量用rpx:responsive pixel,可以根据屏幕宽度进行自适应
- 样式导入使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用“;”表示语句结束。
3.3 数据绑定
在 WXML 中,普通的属性的绑定是单向的。
<input type = "text" value="{{value}}" />
Page({
data: {
value: ""
}
})
如果使用 this.setData({ value: 'leaf' }) 来更新 value ,this.data.value 和输入框的中显示的值都会被更新为 leaf ;但如果用户修改了输入框里的值,却不会同时改变 this.data.value 。
如果需要在用户输入的同时改变 this.data.value ,需要借助简易双向绑定机制。此时,可以在对应项目之前加入 model: 前缀:
<input model:value="{{value}}" />
这样,如果输入框的值被改变了, this.data.value 也会同时改变。同时, WXML 中所有绑定了 value 的位置也会被一同更新。
示例:在文本框中输入值,在view中同步显示。
// index.js
Page({
data: {
value: ""
}
})
<!-- index.wxml -->
<input type = "text" placeholder = "请输入文字" model:value="{{message}}"/>
<view>{{message}}</view>
上面的双向绑定,只能实现简单数据类型(比如字符串、数字)的双向绑定。复杂数据(比如对象、数组)等无法实现双向绑定,比如:
// index.js
Page({
data: {
student: {
id: 1,
name: "张三"
}
}
})
<!-- index.wxml -->
<input type = "text" modal:value = "{{student.name}}">
<view>{{student.name}}</view>
当在文本框中输入值的时候,下面的view中间的文本并没有同步改变,这说明当文本框中的值发生改变的时候,逻辑层中的student对象的name属性值没有发生改变。那如何做到输入框中的值与view的显示同步呢?还是要用输入框的bindinput事件。
// index.js
Page({
data: {
student: {
id: 1,
name: "张三"
}
},
changeValue: function (e) {
this.setData({
"student.name": e.detail.value
})
}
})
<!-- index.wxml -->
<input type = "text" value = "{{student.name}}" bindinput = "changeValue">
<view>{{student.name}}</view>
相关推荐
- 2025南通中考作文解读之四:结构框架
-
文题《继续走,迈向远方》结构框架:清晰叙事,层层递进示例结构:1.开头(点题):用环境描写或比喻引出“走”与“远方”,如“人生如一条长路,每一次驻足后,都需要继续走,才能看见更美的风景”。2.中间...
- 高中数学的知识框架(高中数学知识框架图第三章)
-
高中数学的知识框架可以划分为多个核心板块,每个板块包含具体的知识点与内容,以下为详细的知识框架结构:基础知识1.集合与逻辑用语:涵盖集合的概念、表示方式、性质、运算,以及命题、四种命题关系、充分条件...
- 决定人生的六大框架(决定人生的要素)
-
45岁的自己混到今天,其实是失败的,要是早点意识到影响人生的六大框架,也不至于今天的模样啊!排第一的是环境,不是有句话叫人是环境的产物,身边的环境包括身边的人和事,这些都会对一个人产生深远的影响。其次...
- 2023年想考过一级造价师土建计量,看这30个知识点(三)
-
第二章工程构造考点一:工业建筑分类[考频分析]★★★1.按厂房层数分:(1)单层厂房;(2)多层厂房;(3)混合层数厂房。2.按工业建筑用途分:(1)生产厂房;(2)生产辅助厂房;(3)动力用厂房;(...
- 一级建造师习题集-建筑工程实务(第一章-第二节-2)
-
建筑工程管理与实务题库(章节练习)第一章建筑工程技术第二节结构设计与构造二、结构设计1.常见建筑结构体系中,适用建筑高度最小的是()。A.框架结构体系B.剪力墙结构体系C.框架-剪力墙结构体系D...
- 冷眼读书丨多塔斜拉桥,这么美又这么牛
-
”重大交通基础设施的建设是国民经济和社会发展的先导,是交通运输行业新技术集中应用与创新的综合体现。多塔斜拉桥因跨越能力强、地形适应性强、造型优美等特点,备受桥梁设计者的青睐,在未来跨越海峡工程中将得...
- 2021一级造价师土建计量知识点:民用建筑分类
-
2021造价考试备考开始了,学霸君为大家整理了一级造价师备考所用的知识点,希望对大家的备考道路上有所帮助。 民用建筑分类 一、按层数和高度分 1.住宅建筑按层数分类:1~3层为低层住宅,4~6层...
- 6个建筑结构常见类型,你都知道吗?
-
建筑结构是建筑物中支承荷载(作用)起骨架作用的体系。结构是由构件组成的。构件有拉(压)杆、梁、板、柱、拱、壳、薄膜、索、基础等。常见的建筑结构类型有6种:砖混结构、砖木结构、框架结构、钢筋混凝土结构、...
- 框架结构设计经验总结(框架结构设计应注意哪些问题)
-
1.结构设计说明主要是设计依据,抗震等级,人防等级,地基情况及承载力,防潮抗渗做法,活荷载值,材料等级,施工中的注意事项,选用详图,通用详图或节点,以及在施工图中未画出而通过说明来表达的信息。2.各...
- 浅谈混凝土框架结构设计(混凝土框架结构设计主要内容)
-
浅谈混凝土框架结构设计 摘要:结构设计是个系统的全面的工作,需要扎实的理论知识功底,灵活创新的思维和严肃认真负责的工作态度。钢筋混凝土框架结构虽然相对简单,但设计中仍有很多需要注意的问题。本文针...
- 2022一级建造师《建筑实务》1A412020 结构设计 精细考点整理
-
历年真题分布统计1A412021常用建筑结构体系和应用一、混合结构体系【2012-3】指楼盖和屋盖采用钢筋混凝土或钢木结构,而墙和柱采用砌体结构建造的房屋,大多用在住宅、办公楼、教学楼建筑中。优点:...
- 破土动工!这个故宫“分院”科技含量有点儿高
-
故宫“分院”设计图。受访者供图近日,位于北京海淀区西北旺镇的故宫北院区项目已开始破土动工,该项目也被称作故宫“分院”,筹备近十年之久。据悉,故宫本院每年展览文物的数量不到1万件,但是“分院”建成后,预...
- 装配式结构体系介绍(上)(装配式结构如何设计)
-
PC构件深化、构件之间连接节点做法等与相应装配式结构体系密切相关。本节列举目前常见的几种装配式结构体系:装配整体式混凝土剪力墙结构体系、装配整体式混凝土框架结构体系、装配整体式混凝土空腔结构体系(S...
- 这些不是双向抗侧结构体系(这些不是双向抗侧结构体系的特点)
-
双向抗侧土木吧规范对双向抗恻力结构有何规定?为何不应采用单向有墙的结构?双向抗侧土木吧1.规范对双向抗侧力结构体系的要求抗侧力体系是指抵抗水平地震作用及风荷载的结构体系。对于结构体系的布置,规范针对...
- 2022一级建造师《建筑实务》1A412020 结构设计 精细化考点整理
-
1A412021常用建筑结构体系和应用一、混合结构体系【2012-3】指楼盖和屋盖采用钢筋混凝土或钢木结构,而墙和柱采用砌体结构建造的房屋,大多用在住宅、办公楼、教学楼建筑中。优点:抗压强度高,造价...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- laravel框架 (46)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- winform框架 (46)
- gui框架 (44)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)