目录
一、视图层
1. WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
要完整了解 WXML 语法,请参考WXML 语法参考。
根据我博客中进行创建一个微信小程序项目: 开发微信小程序的下载安装及入门
https://blog.csdn.net/SAME_LOVE/article/details/133826628?spm=1001.2014.3001.5501
之后在项目中增加四个页面,分别命名为 : home,classify,orders,me 。
( 可以根据自己的需求进行更改命名 )
在项目的主体中找到 app.json 这个文件进行增加以上四个文件。
在该文件中找到 pages ,在里面进行直接页面。
"pages":[
"pages/home/home",
"pages/classify/classify",
"pages/orders/orders",
"pages/me/me",
"pages/user/user",
"pages/index/index",
"pages/logs/logs"
],
-
数据绑定
在我们创建的页面中 ( home ) ,在 home.wxml中 编写代码 :
<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<!--wxml-->
<view> {{message}} </view>
在我们创建的页面中 ( home ) ,在 home.js的data中 编写代码 :
/**
* 页面的初始数据
*/
data: {
message: 'Hello MINA ! 欢迎进入 。。 '
},
在模拟器中可以看到的效果 :
-
列表渲染
在我们创建的页面中 ( home ) ,在 home.wxml中 编写代码 :
<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<!--wxml-->
<view> {{message}} </view>
<!--wxml-->
<view wx:for="{{array}}" style="margin-left: 10px;"> {{item}} </view>
在我们创建的页面中 ( home ) ,在 home.js的data中 编写代码 :
data: {
message: 'Hello MINA ! 欢迎进入 。。 ',
array: [1, 2, 3, 4, 5]
},
在模拟器中可以看到的效果 :
-
条件渲染
在我们创建的页面中 ( home ) ,在 home.wxml中 编写代码 :
<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<!--wxml-->
<view> {{message}} </view>
<!--wxml-->
<view wx:for="{{array}}" style="margin-left: 10px;"> {{item}} </view>
<!--wxml-->
<view wx:if="{{view == '1'}}"> 坤坤 </view>
<view wx:elif="{{view == '2'}}"> ikun </view>
<view wx:else="{{view == '3'}}"> 篮球 </view>
在我们创建的页面中 ( home ) ,在 home.js的data中 编写代码 :
/**
* 页面的初始数据
*/
data: {
message: 'Hello MINA ! 欢迎进入 。。 ',
array: [1, 2, 3, 4, 5],
view: '2'
},
在模拟器中可以看到的效果 :
-
模板
在我们创建的页面中 ( home ) ,在 home.wxml中 编写代码 :
<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<!--wxml-->
<view> {{message}} </view>
<!--wxml-->
<view wx:for="{{array}}" style="margin-left: 10px;"> {{item}} </view>
<!--wxml-->
<view wx:if="{{view == '1'}}"> 坤坤 </view>
<view wx:elif="{{view == '2'}}"> ikun </view>
<view wx:else="{{view == '3'}}"> 篮球 </view>
<!--wxml-->
<template name="staffName">
<view>
BookName: {{BookName}}, Author: {{Author}}
</view>
</template>
<template is="staffName" data="{{...BookA}}"></template>
<template is="staffName" data="{{...BookB}}"></template>
<template is="staffName" data="{{...BookC}}"></template>
在我们创建的页面中 ( home ) ,在 home.js的data中 编写代码 :
/**
* 页面的初始数据
*/
data: {
message: 'Hello MINA ! 欢迎进入 。。 ',
array: [1, 2, 3, 4, 5],
view: '2',
BookA: {BookName: '掌中球', Author: '秘名'},
BookB: {BookName: '起飞的小猪', Author: '夏凉'},
BookC: {BookName: '手中棍', Author: '勇者'}
},
在模拟器中可以看到的效果 :
2. WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
-
尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
-
样式导入
使用
@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用
;
表示语句结束。
方法一 :
/** common.wxss **/
.small-p {
padding:5px;
}
方法二 :
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
-
内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
<view style="color:yellow;" />
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
<view class="vi" />
-
选择器
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro | 选择所有拥有 class="intro" 的组件 |
#id | #firstname | 选择拥有 id="firstname" 的组件 |
element | view | 选择所有 view 组件 |
element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容 |
::before | view::before | 在 view 组件前边插入内容 |
全局样式与局部样式 :
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
3. WXS事件
在组件中绑定一个事件处理函数。
如
bindtap
,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
在我们创建的页面中 ( home ) ,在 home.wxml中 编写代码 :
<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<!--wxml-->
<view> {{message}} </view>
<!--wxml-->
<view wx:for="{{array}}" style="margin-left: 10px;"> {{item}} </view>
<!--wxml-->
<view wx:if="{{view == '1'}}"> 坤坤 </view>
<view wx:elif="{{view == '2'}}"> ikun </view>
<view wx:else="{{view == '3'}}"> 篮球 </view>
<!--wxml-->
<template name="staffName">
<view>
BookName: {{BookName}}, Author: {{Author}}
</view>
</template>
<template is="staffName" data="{{...BookA}}"></template>
<template is="staffName" data="{{...BookB}}"></template>
<template is="staffName" data="{{...BookC}}"></template>
<button id="tapTest" data-hi="Weixin" data-name="小君" bindtap="tapName"> Click me! </button>
在我们创建的页面中 ( home ) ,在 home.js中编写代码 :
/**
* 页面的初始数据
*/
data: {
message: 'Hello MINA ! 欢迎进入 。。 ',
array: [1, 2, 3, 4, 5],
view: '2',
BookA: {BookName: '掌中球', Author: '秘名'},
BookB: {BookName: '起飞的小猪', Author: '夏凉'},
BookC: {BookName: '手中棍', Author: '勇者'}
},
/**
* 方法事件
*/
tapName: function(event) {
console.log(event);
console.log(event.target.dataset);
},
所看到的效果如图 :
二、逻辑层
1. 页面生命周期
思维图 :
微信小程序中逻辑层的页面生命周期包括以下几个阶段:
1. onLoad:页面加载时触发,只会触发一次,可以在此处进行页面初始化操作。
2. onShow:页面显示时触发,每次页面显示都会触发,可以在此处进行数据刷新操作。
3. onReady:页面初次渲染完成时触发,只会触发一次,可以在此处进行一些界面操作,如设置导航栏标题等。
4. onHide:页面隐藏时触发,当用户切换到其他页面时触发。
5. onUnload:页面卸载时触发,当用户关闭当前页面或者返回上一页时触发,可以在此处进行一些资源释放操作。
6. onPullDownRefresh:下拉刷新时触发,用户下拉页面时触发,可以在此处进行数据刷新操作。
7. onReachBottom:上拉触底时触发,用户滑动页面到底部时触发,可以在此处进行数据加载操作。
8. onShareAppMessage:分享页面时触发,用户点击分享按钮时触发,可以在此处设置分享内容。
在逻辑层中,可以通过重写这些生命周期函数来实现页面的各种操作和逻辑。
2.跳转
代码:
在项目主体 app.json 中 增加以下代码:
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "欢迎页"
}, {
"pagePath": "pages/logs/logs",
"text": "日志"
},{
"pagePath": "pages/home/home",
"text": "首页"
},{
"pagePath": "pages/me/me",
"text": "我的"
}]
},
在我们创建的页面中 ( home ) ,在 home.wxml中 编写代码 :
<!--pages/home/home.wxml-->
<text>pages/home/home.wxml</text>
<!--wxml-->
<view> {{message}} </view>
<!--wxml-->
<view wx:for="{{array}}" style="margin-left: 10px;"> {{item}} </view>
<!--wxml-->
<view wx:if="{{view == '1'}}"> 坤坤 </view>
<view wx:elif="{{view == '2'}}"> ikun </view>
<view wx:else="{{view == '3'}}"> 篮球 </view>
<!--wxml-->
<template name="staffName">
<view>
BookName: {{BookName}}, Author: {{Author}}
</view>
</template>
<template is="staffName" data="{{...BookA}}"></template>
<template is="staffName" data="{{...BookB}}"></template>
<template is="staffName" data="{{...BookC}}"></template>
<button id="tapTest" data-hi="Weixin" data-name="小君" bindtap="tapName"> Click me! </button>
<button style="margin-top: 20px;" bindtap="bindViewTap">
home 跳转到classify页面&&一级跳二级</button>
在我们创建的页面中 ( home ) ,在 home.js中编写代码 :
// pages/home/home.js
Page({
/**
* 页面的初始数据
*/
data: {
message: 'Hello MINA ! 欢迎进入 。。 ',
array: [1, 2, 3, 4, 5],
view: '2',
BookA: {BookName: '掌中球', Author: '秘名'},
BookB: {BookName: '起飞的小猪', Author: '夏凉'},
BookC: {BookName: '手中棍', Author: '勇者'}
},
/**
* 方法事件
*/
tapName: function(event) {
console.log(event);
console.log(event.target.dataset);
},
// 事件处理函数
bindViewTap() {
wx.navigateTo({
url: '/pages/classify/classify',
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log("home.onLoad");
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
console.log("home.onReady");
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
console.log("home.onShow");
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
console.log("home.onHide");
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
console.log("home.onUnload");
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
在我们创建的页面中 ( classify) ,在 classify.wxml中 编写代码 :
<!--pages/classify/classify.wxml-->
<text>pages/classify/classify.wxml</text>
<button bindtap="bindViewTap">
classify跳转到orders二级跳二级</button>
在我们创建的页面中 ( classify) ,在 classify.js中编写代码 :
// pages/classify/classify.js
Page({
/**
* 页面的初始数据
*/
data: {
},
// 事件处理函数
bindViewTap() {
wx.navigateTo({
url: '/pages/orders/orders',
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log("classify.onLoad");
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
console.log("classify.onReady");
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
console.log("classify.onShow");
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
console.log("classify.onHide");
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
console.log("classify.onUnload");
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
在我们创建的页面中 ( orders) ,在 orders.wxml中 编写代码 :
<!--pages/orders/orders.wxml-->
<text>pages/orders/orders.wxml</text>
<button style="margin-top: 20px;" bindtap="bindViewTap">
orders跳转到home页面&&二级跳一级</button>
在我们创建的页面中 ( orders) ,在 orders.js中编写代码 :
// pages/orders/orders.js
Page({
/**
* 页面的初始数据
*/
data: {
},
// 事件处理函数
bindViewTap() {
wx.switchTab({
url: '/pages/home/home',
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log("orders.onLoad");
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
console.log("orders.onReady");
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
console.log("orders.onShow");
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
console.log("orders.onHide");
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
console.log("orders.onUnload");
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
在我们创建的页面中 ( me) ,在 me.js中编写代码 :
// pages/me/me.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log("me.onLoad");
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
console.log("me.onReady");
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
console.log("me.onShow");
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
console.log("me.onHide");
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
console.log("me.onUnload");
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
1. 一级跳一级
效果如图 :
2. 一级跳二级
效果如图 :
3. 二级跳二级
效果如图 :
4. 二级跳一级
效果如图 :
总结
- 一级页面不会销毁
- 一级层级跳到子级层级,或者子级层级跳到子级层级,如: 一级跳二级,二级跳二级,二级跳三级,三级跳四级,以上路由跳法,上一级隐藏,下一级显示(初次显示会调用onLoad,onReady,onShow方法) ; 如果是从下级返回到上级,下级将会被销毁。上级显示(初次显示会调用onLoad,onReady,onShow方法) ;
- 隔代返回的话,会将中间所有的子级进行销毁。如 : 四级返回到一级或者跳转到一级,中间的四级,三级,二级都将被销毁,而一级会显示(初次显示会调用onLoad,onReady,onShow方法) ;
带给我们的收获
学习微信小程序中的视图层和逻辑层级页面的生命周期可以带来以下收获:
1. 理解小程序的整体架构:学习视图层和逻辑层的生命周期可以帮助我们更好地理解小程序的整体架构,从而更好地设计和开发小程序。
2. 控制页面的生命周期:通过学习生命周期,我们可以了解到页面在不同阶段会触发哪些事件,从而可以在不同的生命周期中执行相应的操作,例如在页面加载时请求数据,在页面卸载时清理资源等。
3. 实现页面交互和动画效果:通过生命周期函数,我们可以在页面的不同阶段执行相应的操作,例如在页面显示时执行动画效果,给用户更好的交互体验。
4. 优化小程序性能:了解生命周期可以帮助我们更好地管理页面的资源和数据,从而优化小程序的性能,例如及时释放不需要的资源,避免内存泄漏等。
5. 调试和排查问题:当遇到问题时,了解生命周期可以帮助我们更好地定位问题所在,例如通过打印生命周期函数的日志来查看页面的加载和卸载情况,从而排查问题。
总之,学习微信小程序中的视图层和逻辑层级页面的生命周期可以帮助我们更好地理解和掌握小程序的开发,提高开发效率和用户体验。